void GfxCursor32::setRestrictedArea(const Common::Rect &rect) { _restrictedArea = rect; const int16 screenWidth = g_sci->_gfxFrameout->getCurrentBuffer().screenWidth; const int16 screenHeight = g_sci->_gfxFrameout->getCurrentBuffer().screenHeight; const int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth; const int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight; mulru(_restrictedArea, Ratio(screenWidth, scriptWidth), Ratio(screenHeight, scriptHeight), 0); if (_position.x < rect.left) { _position.x = rect.left; } if (_position.x >= rect.right) { _position.x = rect.right - 1; } if (_position.y < rect.top) { _position.y = rect.top; } if (_position.y >= rect.bottom) { _position.y = rect.bottom - 1; } g_system->warpMouse(_position.x, _position.y); }
static bool IsEdge(const GLIX &HitGlix, const HitData &Hit, int i, int j) { if (i == j) return false; assert(i >= 0 && i < CandCount); assert(j >= 0 && j < CandCount); const HitData &Hit_i = Cands[i]; const HitData &Hit_j = Cands[j]; const int HitLength = GetHitLength(Hit); const int HitLength_i = GetHitLength(Hit_i); const int HitLength_j = GetHitLength(Hit_j); if (Ratio(HitLength, HitLength_i) < MIN_HIT_LENGTH_RATIO || Ratio(HitLength, HitLength_j) < MIN_HIT_LENGTH_RATIO || Ratio(HitLength_i, HitLength_j) < MIN_HIT_LENGTH_RATIO) return false; const int LINELength_i = GetLINELength(Hit_i); const int LINELength_j = GetLINELength(Hit_j); if (Ratio(LINELength_i, LINELength_j) < MIN_LINE_RATIO) return false; if (TooClose(HitGlix, Hit_i, Hit_j)) return false; return true; }
reg_t GfxText32::createFontBitmap(const CelInfo32 &celInfo, const Common::Rect &rect, const Common::String &text, const int16 foreColor, const int16 backColor, const GuiResourceId fontId, const int16 skipColor, const int16 borderColor, const bool dimmed, const bool gc) { _borderColor = borderColor; _text = text; _textRect = rect; _foreColor = foreColor; _dimmed = dimmed; setFont(fontId); int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth; int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight; mulinc(_textRect, Ratio(_xResolution, scriptWidth), Ratio(_yResolution, scriptHeight)); CelObjView view(celInfo.resourceId, celInfo.loopNo, celInfo.celNo); _skipColor = view._skipColor; _width = view._width * _xResolution / view._xResolution; _height = view._height * _yResolution / view._yResolution; Common::Rect bitmapRect(_width, _height); if (_textRect.intersects(bitmapRect)) { _textRect.clip(bitmapRect); } else { _textRect = Common::Rect(); } SciBitmap &bitmap = *_segMan->allocateBitmap(&_bitmap, _width, _height, _skipColor, 0, 0, _xResolution, _yResolution, 0, false, gc); // NOTE: The engine filled the bitmap pixels with 11 here, which is silly // because then it just erased the bitmap using the skip color. So we don't // fill the bitmap redundantly here. _backColor = _skipColor; erase(bitmapRect, false); _backColor = backColor; view.draw(bitmap.getBuffer(), bitmapRect, Common::Point(0, 0), false, Ratio(_xResolution, view._xResolution), Ratio(_yResolution, view._yResolution)); if (_backColor != skipColor && _foreColor != skipColor) { erase(_textRect, false); } if (text.size() > 0) { if (_foreColor == skipColor) { error("TODO: Implement transparent text"); } else { if (borderColor != -1) { drawFrame(bitmapRect, 1, _borderColor, false); } drawTextBox(); } } return _bitmap; }
Ratio DrawLab::Zoom(Coord delta) { if( delta>0 ) { return Ratio(17,4).pow(delta); } else { return Ratio(15,4).pow(-delta); } }
void GfxCursor32::setPosition(const Common::Point &position) { const int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth; const int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight; const int16 screenWidth = g_sci->_gfxFrameout->getCurrentBuffer().screenWidth; const int16 screenHeight = g_sci->_gfxFrameout->getCurrentBuffer().screenHeight; _position.x = (position.x * Ratio(screenWidth, scriptWidth)).toInt(); _position.y = (position.y * Ratio(screenHeight, scriptHeight)).toInt(); g_system->warpMouse(_position.x, _position.y); }
void ExerciseCompare::createTask() { // generate the first ratio m_firstRatio = Ratio(int ((double(rand()) / RAND_MAX) * 10 + 1), int ((double(rand()) / RAND_MAX) * 10 + 1)); // now the second ratio, but make sure, the second ratio is different from // the first one do { m_secondRatio = Ratio(int ((double(rand()) / RAND_MAX) * 10 + 1), int ((double(rand()) / RAND_MAX) * 10 + 1)); } while (m_firstRatio == m_secondRatio); return; }
void FractionPainter::paintWidget(QPainter & paint) { // our x position, we paint from left to right; // we don't want to start directly on the border, so add the margin int old_x = _MARGIN_X; int old_y = 0; // ratios and operation signs are painted with the same font m_font.setPointSize(24); m_font.setBold(true); paint.setFont(m_font); // set the pen for painting QPen pen(Qt::SolidLine); pen.setWidth(0); paint.setPen(pen); // get the font height; the font height doesn't change while painting QFontMetrics fm(paint.fontMetrics()); // now we can correctly set the height of the widget setMinimumHeight(2 * fm.lineSpacing() + 10); setMaximumHeight(2 * fm.lineSpacing() + 10); // get the current ratio and paint it paintRatio(paint, Ratio(leftRatio.numerator() * leftMult, leftRatio.denominator() * leftMult, false), old_x, old_y, fm); if (leftRatio.denominator() * leftMult < 10) old_x += 40; else old_x += 25; // paint the operation paintMiddle(paint, str_operation, old_x, old_y, fm, m_colorOperation); if (rightRatio.denominator() * rightMult < 10) old_x += 40; else old_x += 25; // get the current ratio and paint it paintRatio(paint, Ratio(rightRatio.numerator() * rightMult, rightRatio.denominator() * rightMult, false), old_x, old_y, fm); // stop the painter paint.end(); // the space we needed for painting is the minimum width of the widget setMinimumWidth(old_x); }
reg_t kCelWide32(EngineState *s, int argc, reg_t *argv) { GuiResourceId resourceId = argv[0].toUint16(); int16 loopNo = argv[1].toSint16(); int16 celNo = argv[2].toSint16(); CelObjView celObj(resourceId, loopNo, celNo); return make_reg(0, mulru(celObj._width, Ratio(g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth, celObj._scaledWidth))); }
ScrollWindow::ScrollWindow(SegManager *segMan, const Common::Rect &gameRect, const Common::Point &position, const reg_t plane, const uint8 defaultForeColor, const uint8 defaultBackColor, const GuiResourceId defaultFontId, const TextAlign defaultAlignment, const int16 defaultBorderColor, const uint16 maxNumEntries) : _segMan(segMan), _gfxText32(segMan, g_sci->_gfxCache), _maxNumEntries(maxNumEntries), _firstVisibleChar(0), _topVisibleLine(0), _lastVisibleChar(0), _bottomVisibleLine(0), _numLines(0), _numVisibleLines(0), _plane(plane), _foreColor(defaultForeColor), _backColor(defaultBackColor), _borderColor(defaultBorderColor), _fontId(defaultFontId), _alignment(defaultAlignment), _visible(false), _position(position), _screenItem(nullptr), _nextEntryId(1) { _entries.reserve(maxNumEntries); _gfxText32.setFont(_fontId); _pointSize = _gfxText32._font->getHeight(); const uint16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth; const uint16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight; Common::Rect bitmapRect(gameRect); mulinc(bitmapRect, Ratio(_gfxText32._scaledWidth, scriptWidth), Ratio(_gfxText32._scaledHeight, scriptHeight)); _textRect.left = 2; _textRect.top = 2; _textRect.right = bitmapRect.width() - 2; _textRect.bottom = bitmapRect.height() - 2; uint8 skipColor = 0; while (skipColor == _foreColor || skipColor == _backColor) { skipColor++; } assert(bitmapRect.width() > 0 && bitmapRect.height() > 0); _bitmap = _gfxText32.createFontBitmap(bitmapRect.width(), bitmapRect.height(), _textRect, "", _foreColor, _backColor, skipColor, _fontId, _alignment, _borderColor, false, false, false); debugC(1, kDebugLevelGraphics, "New ScrollWindow: textRect size: %d x %d, bitmap: %04x:%04x", _textRect.width(), _textRect.height(), PRINT_REG(_bitmap)); }
void fire(WeaponType const& self, State& state, TransientState& transient_state, Scalar angle, Vector2 vel, Vector2 pos, i16 owner) { //auto& mod = state.mod; if (owner >= 0) { auto& worm = state.worms.of_index(owner); worm.muzzle_fire = self.muzzle_fire(); } /* if(w.leaveShells > 0) <-- { if(game.rand(w.leaveShells) == 0) { leaveShellTimer = w.leaveShellDelay; } } if(w.launchSound >= 0) { if(w.loopSound) { if(!game.soundPlayer->isPlaying(&weapons[currentWeapon])) { game.soundPlayer->play(w.launchSound, &weapons[currentWeapon], -1); } } else { game.soundPlayer->play(w.launchSound); } } */ // TODO: Looping? transient_state.play_sound(state.mod, self.fire_sound(), transient_state); auto dir = sincos(angle); auto anglevel = vel * self.worm_vel_ratio() + dir * self.speed(); pos += dir * i32(self.fire_offset()); auto& ty = state.mod.get_nobject_type(self.nobject_type()); u32 lparts = self.parts(); for (u32 i = 0; i < lparts; ++i) { auto part_vel = anglevel; if (self.distribution() != Ratio()) { part_vel += rand_max_vector2(state.rand, self.distribution()); } create(ty, state, angle, pos, part_vel, owner); } }
void DiscreteJacobianField::CommonConstruct(const Array<Matrix> & inverse_jacobians_in, const float r_value) { inverse_jacobians_in.Size(_data_size); _forward_jacobians = _inverse_jacobians = inverse_jacobians_in; // compute forward jacobians vector<Matrix> inverse_jacobians; if(! _inverse_jacobians.Get(inverse_jacobians)) throw Exception("SampledJacobianField::SampledJacobianField(): cannot get inverse jacobians"); vector<Matrix> forward_jacobians(inverse_jacobians); for(unsigned int i = 0; i < forward_jacobians.size(); i++) { if(! inverse_jacobians[i].Inverse(forward_jacobians[i])) throw Exception("SampledJacobianField::SampledJacobianField(): cannot compute forward jacobian"); } // computation const int dimension = Dimension(); if(! EigenComputation(FORWARD, dimension, forward_jacobians, _forward_mean_eigen_value, _forward_max_eigen_value, _forward_min_eigen_value)) throw Exception("SampledJacobianField::SampledJacobianField(): cannot eigen compute forward jacobians"); if(! EigenComputation(INVERSE, dimension, inverse_jacobians, _inverse_mean_eigen_value, _inverse_max_eigen_value, _inverse_min_eigen_value)) throw Exception("SampledJacobianField::SampledJacobianField(): cannot eigen compute inverse jacobians"); const float forward_ratio = (r_value > 0 ? Ratio(FORWARD, r_value, _forward_mean_eigen_value) : 1.0); const float inverse_ratio = (r_value > 0 ? Ratio(INVERSE, r_value, _inverse_mean_eigen_value) : 1.0); for(unsigned int i = 0; i < forward_jacobians.size(); i++) { forward_jacobians[i].Multiply(forward_ratio); } _forward_mean_eigen_value *= forward_ratio; _forward_max_eigen_value *= forward_ratio; _forward_min_eigen_value *= forward_ratio; for(unsigned int i = 0; i < inverse_jacobians.size(); i++) { inverse_jacobians[i].Multiply(inverse_ratio); } _inverse_mean_eigen_value *= inverse_ratio; _inverse_max_eigen_value *= inverse_ratio; _inverse_min_eigen_value *= inverse_ratio; // put back if(! _inverse_jacobians.Put(inverse_jacobians)) throw Exception("SampledJacobianField::SampledJacobianField(): cannot put inverse jacobians"); if(! _forward_jacobians.Put(forward_jacobians)) throw Exception("SampledJacobianField::SampledJacobianField(): cannot put forward jacobians"); }
int UploadRatio(const acl::User& user, const fs::VirtualPath& path, const boost::optional<const cfg::Section&>& section) { if (section) { int ratio = user.SectionRatio(section->Name()); if (ratio >= 0) return ratio; } auto cc = acl::CreditCheck(user, path); if (cc && cc->Ratio() >= 0) return cc->Ratio(); if (section && section->Ratio() >= 0) return section->Ratio(); assert(user.DefaultRatio() >= 0); return user.DefaultRatio(); }
int DownloadRatio(const acl::User& user, const fs::VirtualPath& path, const boost::optional<const cfg::Section&>& section) { if (acl::path::FileAllowed<acl::path::Freefile>(user, path)) return 0; if (section) { int ratio = user.SectionRatio(section->Name()); if (ratio == 0) return 0; } auto cl = acl::CreditLoss(user, path); if (cl && cl->Ratio() >= 0) return cl->Ratio(); if (section && section->Ratio() >= 0) return section->Ratio(); assert(user.DefaultRatio() >= 0); return user.DefaultRatio() == 0 ? 0 : 1; }
void QSimplexConstraint::invert() { constant = -constant; ratio = Ratio(2 - ratio); QHash<QSimplexVariable *, qreal>::iterator iter; for (iter = variables.begin(); iter != variables.end(); ++iter) { iter.value() = -iter.value(); } }
//------------------------------------------------------------------------------ // RatioError //------------------------------------------------------------------------------ Double_t RatioError(Double_t a, Double_t b, Double_t aErr, Double_t bErr) { if (b == 0) return 0.0; if (aErr < 0) aErr = sqrt(a); if (bErr < 0) bErr = sqrt(b); return Ratio(a,b) * sqrt((aErr/a)*(aErr/a) + (bErr/b)*(bErr/b)); }
int16 GfxText32::getTextCount(const Common::String &text, const uint index, const Common::Rect &textRect, const bool doScaling) { const int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth; const int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight; Common::Rect scaledRect(textRect); if (doScaling) { mulinc(scaledRect, Ratio(_xResolution, scriptWidth), Ratio(_yResolution, scriptHeight)); } Common::String oldText = _text; _text = text; uint charIndex = index; int16 maxWidth = scaledRect.width(); int16 lineCount = (scaledRect.height() - 2) / _font->getHeight(); while (lineCount--) { getLongest(&charIndex, maxWidth); } _text = oldText; return charIndex - index; }
int main() { freopen("approximate.in", "r", stdin); freopen("approximate2.out", "w", stdout); int a, b, n; scanf("%d%d%d", &a, &b, &n); int ans = 1; Ratio const need(a, b); Ratio best(2 * a > b ? 1 : 0, 1); if (a * 2 == b) { ++ans; } for (int y = 2; y <= n; ++y) { int x = (long long) y * a / b; Ratio now1 = Ratio(x, y); Ratio now2 = Ratio(x + 1, y); bool ok1 = better(now1, best, need); bool ok2 = better(now2, best, need); if (!ok1 || !ok2) { ans += ok1 + ok2; if (ok1) best = now1; if (ok2) best = now2; } else { if (better(now1, now2, need)) { ++ans; best = now1; } else if (better(now2, now1, need)) { ++ans; best = now2; } else { ans += 2; best = now1; } } } printf("%d\n", ans); }
static int AddStats(DBProvider * pdb, int gm_id, int player_id, int player, const char *table, int nMatchTo, statcontext * sc) { gchar *buf; GString *column, *value; int totalmoves, unforced; float errorcost, errorskill; float aaaar[3][2][2][2]; float r; int ret; char tmpf[G_ASCII_DTOSTR_BUF_SIZE]; int gms_id = GetNextId(pdb, table); if (gms_id == -1) return FALSE; totalmoves = sc->anTotalMoves[player]; unforced = sc->anUnforcedMoves[player]; getMWCFromError(sc, aaaar); errorskill = aaaar[CUBEDECISION][PERMOVE][player][NORMALISED]; errorcost = aaaar[CUBEDECISION][PERMOVE][player][UNNORMALISED]; column = g_string_new(NULL); value = g_string_new(NULL); if (strcmp("matchstat", table) == 0) { APPENDI("matchstat_id", gms_id); APPENDI("session_id", gm_id); } else { APPENDI("gamestat_id", gms_id); APPENDI("game_id", gm_id); } APPENDI("player_id", player_id); APPENDI("total_moves", totalmoves); APPENDI("unforced_moves", unforced); APPENDI("unmarked_moves", sc->anMoves[player][SKILL_NONE]); APPENDI("good_moves", 0); APPENDI("doubtful_moves", sc->anMoves[player][SKILL_DOUBTFUL]); APPENDI("bad_moves", sc->anMoves[player][SKILL_BAD]); APPENDI("very_bad_moves", sc->anMoves[player][SKILL_VERYBAD]); APPENDF("chequer_error_total_normalised", sc->arErrorCheckerplay[player][0]); APPENDF("chequer_error_total", sc->arErrorCheckerplay[player][1]); APPENDF("chequer_error_per_move_normalised", Ratio(sc->arErrorCheckerplay[player][0], unforced)); APPENDF("chequer_error_per_move", Ratio(sc->arErrorCheckerplay[player][1], unforced)); APPENDI("chequer_rating", GetRating(Ratio (scMatch.arErrorCheckerplay[player][0], unforced))); APPENDI("very_lucky_rolls", sc->anLuck[player][LUCK_VERYGOOD]); APPENDI("lucky_rolls", sc->anLuck[player][LUCK_GOOD]); APPENDI("unmarked_rolls", sc->anLuck[player][LUCK_NONE]); APPENDI("unlucky_rolls", sc->anLuck[player][LUCK_BAD]); APPENDI("very_unlucky_rolls", sc->anLuck[player][LUCK_VERYBAD]); APPENDF("luck_total_normalised", sc->arLuck[player][0]); APPENDF("luck_total", sc->arLuck[player][1]); APPENDF("luck_per_move_normalised", Ratio(sc->arLuck[player][0], totalmoves)); APPENDF("luck_per_move", Ratio(sc->arLuck[player][1], totalmoves)); APPENDI("luck_rating", getLuckRating(Ratio(sc->arLuck[player][0], totalmoves))); APPENDI("total_cube_decisions", sc->anTotalCube[player]); APPENDI("close_cube_decisions", sc->anCloseCube[player]); APPENDI("doubles", sc->anDouble[player]); APPENDI("takes", sc->anTake[player]); APPENDI("passes", sc->anPass[player]); APPENDI("missed_doubles_below_cp", sc->anCubeMissedDoubleDP[player]); APPENDI("missed_doubles_above_cp", sc->anCubeMissedDoubleTG[player]); APPENDI("wrong_doubles_below_dp", sc->anCubeWrongDoubleDP[player]); APPENDI("wrong_doubles_above_tg", sc->anCubeWrongDoubleTG[player]); APPENDI("wrong_takes", sc->anCubeWrongTake[player]); APPENDI("wrong_passes", sc->anCubeWrongPass[player]); APPENDF("error_missed_doubles_below_cp_normalised", sc->arErrorMissedDoubleDP[player][0]); APPENDF("error_missed_doubles_above_cp_normalised", sc->arErrorMissedDoubleTG[player][0]); APPENDF("error_wrong_doubles_below_dp_normalised", sc->arErrorWrongDoubleDP[player][0]); APPENDF("error_wrong_doubles_above_tg_normalised", sc->arErrorWrongDoubleTG[player][0]); APPENDF("error_wrong_takes_normalised", sc->arErrorWrongTake[player][0]); APPENDF("error_wrong_passes_normalised", sc->arErrorWrongPass[player][0]); APPENDF("error_missed_doubles_below_cp", sc->arErrorMissedDoubleDP[player][1]); APPENDF("error_missed_doubles_above_cp", sc->arErrorMissedDoubleTG[player][1]); APPENDF("error_wrong_doubles_below_dp", sc->arErrorWrongDoubleDP[player][1]); APPENDF("error_wrong_doubles_above_tg", sc->arErrorWrongDoubleTG[player][1]); APPENDF("error_wrong_takes", sc->arErrorWrongTake[player][1]); APPENDF("error_wrong_passes", sc->arErrorWrongPass[player][1]); APPENDF("cube_error_total_normalised", errorskill * sc->anCloseCube[player]); APPENDF("cube_error_total", errorcost * sc->anCloseCube[player]); APPENDF("cube_error_per_move_normalised", errorskill); APPENDF("cube_error_per_move", errorcost); APPENDI("cube_rating", GetRating(errorskill));; APPENDF("overall_error_total_normalised", errorskill * sc->anCloseCube[player] + sc->arErrorCheckerplay[player][0]); APPENDF("overall_error_total", errorcost * sc->anCloseCube[player] + sc->arErrorCheckerplay[player][1]); APPENDF("overall_error_per_move_normalised", Ratio(errorskill * sc->anCloseCube[player] + sc->arErrorCheckerplay[player][0], sc->anCloseCube[player] + unforced)); APPENDF("overall_error_per_move", Ratio(errorcost * sc->anCloseCube[player] + sc->arErrorCheckerplay[player][1], sc->anCloseCube[player] + unforced)); APPENDI("overall_rating", GetRating(Ratio (errorskill * sc->anCloseCube[player] + sc->arErrorCheckerplay[player][0], sc->anCloseCube[player] + unforced))); APPENDF("actual_result", sc->arActualResult[player]); APPENDF("luck_adjusted_result", sc->arLuckAdj[player]); APPENDI("snowie_moves", totalmoves + scMatch.anTotalMoves[!player]); APPENDF("snowie_error_rate_per_move", Ratio(errorskill * scMatch.anCloseCube[player] + scMatch.arErrorCheckerplay[player][0], totalmoves + scMatch.anTotalMoves[!player])); /*time */ APPENDI("time_penalties", 0); APPENDF("time_penalty_loss_normalised", 0.0); APPENDF("time_penalty_loss", 0.0); /* matches only */ r = 0.5f + scMatch.arActualResult[player] - scMatch.arLuck[player][1] + scMatch.arLuck[!player][1]; if (nMatchTo && r > 0.0f && r < 1.0f) APPENDF("luck_based_fibs_rating_diff", relativeFibsRating(r, nMatchTo)); if (nMatchTo && (scMatch.fCube || scMatch.fMoves)) { APPENDF("error_based_fibs_rating", absoluteFibsRating(aaaar[CHEQUERPLAY][PERMOVE] [player][NORMALISED], aaaar[CUBEDECISION][PERMOVE] [player][NORMALISED], nMatchTo, rRatingOffset)); if (scMatch.anUnforcedMoves[player]) APPENDF("chequer_rating_loss", absoluteFibsRatingChequer(aaaar [CHEQUERPLAY] [PERMOVE][player] [NORMALISED], nMatchTo)); if (scMatch.anCloseCube[player]) APPENDF("cube_rating_loss", absoluteFibsRatingCube(aaaar[CUBEDECISION] [PERMOVE][player] [NORMALISED], nMatchTo)); } /* for money sessions only */ if (scMatch.fDice && !nMatchTo && scMatch.nGames > 1) { APPENDF("actual_advantage", scMatch.arActualResult[player] / scMatch.nGames); APPENDF("actual_advantage_ci", 1.95996f * sqrt(scMatch.arVarianceActual[player] / scMatch.nGames)); APPENDF("luck_adjusted_advantage", scMatch.arLuckAdj[player] / scMatch.nGames); APPENDF("luck_adjusted_advantage_ci", 1.95996f * sqrt(scMatch.arVarianceLuckAdj[player] / scMatch.nGames)); } g_string_truncate(column, column->len - 2); g_string_truncate(value, value->len - 2); buf = g_strdup_printf("INSERT INTO %s (%s) VALUES(%s)", table, column->str, value->str); ret = pdb->UpdateCommand(buf); g_free(buf); g_string_free(column, TRUE); g_string_free(value, TRUE); return ret; }
Ratio operator-(Ratio const& a, Ratio const& b) { return Ratio(a.num * b.den - b.num * a.den, a.den * b.den); }
TEST_F(SettingsTest, AddSettingRatio) { settings.add("test_setting", "1.618"); EXPECT_DOUBLE_EQ(Ratio(0.01618), settings.get<Ratio>("test_setting")) << "With ratios, the input is interpreted in percentages."; }
SciEvent EventManager::getScummVMEvent() { #ifdef ENABLE_SCI32 SciEvent input = { SCI_EVENT_NONE, 0, 0, Common::Point(), Common::Point() }; SciEvent noEvent = { SCI_EVENT_NONE, 0, 0, Common::Point(), Common::Point() }; #else SciEvent input = { SCI_EVENT_NONE, 0, 0, Common::Point() }; SciEvent noEvent = { SCI_EVENT_NONE, 0, 0, Common::Point() }; #endif Common::EventManager *em = g_system->getEventManager(); Common::Event ev; bool found = em->pollEvent(ev); // Don't generate events for mouse movement while (found && ev.type == Common::EVENT_MOUSEMOVE) found = em->pollEvent(ev); // Save the mouse position // // We call getMousePos of the event manager here, since we also want to // store the mouse position in case of keyboard events, which do not feature // any mouse position information itself. // This should be safe, since the mouse position in the event manager should // only be updated when a mouse related event has been taken from the queue // via pollEvent. // We also adjust the position based on the scaling of the screen. Common::Point mousePos = em->getMousePos(); #if ENABLE_SCI32 if (getSciVersion() >= SCI_VERSION_2) { Buffer &screen = g_sci->_gfxFrameout->getCurrentBuffer(); Common::Point mousePosSci = mousePos; mulru(mousePosSci, Ratio(screen.scriptWidth, screen.screenWidth), Ratio(screen.scriptHeight, screen.screenHeight)); noEvent.mousePosSci = input.mousePosSci = mousePosSci; } else { #endif g_sci->_gfxScreen->adjustBackUpscaledCoordinates(mousePos.y, mousePos.x); #if ENABLE_SCI32 } #endif noEvent.mousePos = input.mousePos = mousePos; if (!found || ev.type == Common::EVENT_MOUSEMOVE) { int modifiers = em->getModifierState(); noEvent.modifiers = ((modifiers & Common::KBD_ALT) ? SCI_KEYMOD_ALT : 0) | ((modifiers & Common::KBD_CTRL) ? SCI_KEYMOD_CTRL : 0) | ((modifiers & Common::KBD_SHIFT) ? SCI_KEYMOD_LSHIFT | SCI_KEYMOD_RSHIFT : 0); return noEvent; } if (ev.type == Common::EVENT_QUIT) { input.type = SCI_EVENT_QUIT; return input; } int scummVMKeyFlags; switch (ev.type) { case Common::EVENT_KEYDOWN: case Common::EVENT_KEYUP: // Use keyboard modifiers directly in case this is a keyboard event scummVMKeyFlags = ev.kbd.flags; break; default: // Otherwise get them from EventManager scummVMKeyFlags = em->getModifierState(); break; } input.modifiers = ((scummVMKeyFlags & Common::KBD_ALT) ? SCI_KEYMOD_ALT : 0) | ((scummVMKeyFlags & Common::KBD_CTRL) ? SCI_KEYMOD_CTRL : 0) | ((scummVMKeyFlags & Common::KBD_SHIFT) ? SCI_KEYMOD_LSHIFT | SCI_KEYMOD_RSHIFT : 0); // Caps lock and Scroll lock have been removed, cause we already handle upper // case keys and Scroll lock doesn't seem to be used anywhere //((ourModifiers & Common::KBD_CAPS) ? SCI_KEYMOD_CAPSLOCK : 0) | //((ourModifiers & Common::KBD_SCRL) ? SCI_KEYMOD_SCRLOCK : 0) | // Handle mouse events for (int i = 0; i < ARRAYSIZE(mouseEventMappings); i++) { if (mouseEventMappings[i].commonType == ev.type) { input.type = mouseEventMappings[i].sciType; // Sierra passed keyboard modifiers for mouse events, too. // Sierra also set certain modifiers within their mouse interrupt handler // This whole thing was probably meant for people using a mouse, that only featured 1 button // So the user was able to press Ctrl and click the mouse button to create a right click. switch (ev.type) { case Common::EVENT_RBUTTONDOWN: // right button case Common::EVENT_RBUTTONUP: input.modifiers |= (SCI_KEYMOD_RSHIFT | SCI_KEYMOD_LSHIFT); // this value was hardcoded in the mouse interrupt handler break; case Common::EVENT_MBUTTONDOWN: // middle button case Common::EVENT_MBUTTONUP: input.modifiers |= SCI_KEYMOD_CTRL; // this value was hardcoded in the mouse interrupt handler break; default: break; } return input; } } // If we reached here, make sure that it's a keydown event if (ev.type != Common::EVENT_KEYDOWN) return noEvent; // Check for Control-Shift-D (debug console) if (ev.kbd.hasFlags(Common::KBD_CTRL | Common::KBD_SHIFT) && ev.kbd.keycode == Common::KEYCODE_d) { // Open debug console Console *con = g_sci->getSciDebugger(); con->attach(); return noEvent; } // Process keyboard events bool numlockOn = (ev.kbd.flags & Common::KBD_NUM); Common::KeyCode scummVMKeycode = ev.kbd.keycode; input.character = ev.kbd.ascii; input.type = SCI_EVENT_KEYBOARD; if (scummVMKeycode >= Common::KEYCODE_KP0 && scummVMKeycode <= Common::KEYCODE_KP9) { if (!(scummVMKeyFlags & Common::KBD_NUM)) { // HACK: Num-Lock not enabled // We shouldn't get a valid ascii code in these cases. We fix it here, so that cursor keys // on the numpad work properly. input.character = 0; } } if ((input.character) && (input.character <= 0xFF)) { // Directly accept most common keys without conversion if ((input.character >= 0x80) && (input.character <= 0xFF)) { // If there is no extended font, we will just clear the // current event. // Sierra SCI actually accepted those characters, but // didn't display them inside text edit controls because // the characters were missing inside the font(s). // We filter them out for non-multilingual games because // of that. if (!_fontIsExtended) return noEvent; // Convert 8859-1 characters to DOS (cp850/437) for // multilingual SCI01 games input.character = codePageMap88591ToDOS[input.character & 0x7f]; } if (scummVMKeycode == Common::KEYCODE_TAB) { input.character = SCI_KEY_TAB; if (scummVMKeyFlags & Common::KBD_SHIFT) input.character = SCI_KEY_SHIFT_TAB; } if (scummVMKeycode == Common::KEYCODE_DELETE) input.character = SCI_KEY_DELETE; } else if ((scummVMKeycode >= Common::KEYCODE_F1) && scummVMKeycode <= Common::KEYCODE_F10) { // SCI_K_F1 == 59 << 8 // SCI_K_SHIFT_F1 == 84 << 8 if (!(scummVMKeyFlags & Common::KBD_SHIFT)) input.character = SCI_KEY_F1 + ((scummVMKeycode - Common::KEYCODE_F1)<<8); else input.character = SCI_KEY_SHIFT_F1 + ((scummVMKeycode - Common::KEYCODE_F1)<<8); } else { // Special keys that need conversion for (int i = 0; i < ARRAYSIZE(keyMappings); i++) { if (keyMappings[i].scummVMKey == scummVMKeycode) { input.character = numlockOn ? keyMappings[i].sciKeyNumlockOn : keyMappings[i].sciKeyNumlockOff; break; } } } // When Ctrl AND Alt are pressed together with a regular key, Linux will give us control-key, Windows will give // us the actual key. My opinion is that windows is right, because under DOS the keys worked the same, anyway // we support the other case as well if ((scummVMKeyFlags & Common::KBD_ALT) && input.character > 0 && input.character < 27) input.character += 96; // 0x01 -> 'a' // Scancodify if appropriate if (scummVMKeyFlags & Common::KBD_ALT) input.character = altify(input.character); if (getSciVersion() <= SCI_VERSION_1_MIDDLE && (scummVMKeyFlags & Common::KBD_CTRL) && input.character > 0 && input.character < 27) input.character += 96; // 0x01 -> 'a' #ifdef ENABLE_SCI32 if (getSciVersion() >= SCI_VERSION_2 && (scummVMKeyFlags & Common::KBD_CTRL) && input.character == 'c') { input.character = SCI_KEY_ETX; } #endif // If no actual key was pressed (e.g. if only a modifier key was pressed), // ignore the event if (!input.character) return noEvent; return input; }
void ScreenItem::calcRects(const Plane &plane) { const int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth; const int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight; const int16 screenWidth = g_sci->_gfxFrameout->getCurrentBuffer().screenWidth; const int16 screenHeight = g_sci->_gfxFrameout->getCurrentBuffer().screenHeight; const CelObj &celObj = getCelObj(); Common::Rect celRect(celObj._width, celObj._height); if (_useInsetRect) { if (_insetRect.intersects(celRect)) { _insetRect.clip(celRect); } else { _insetRect = Common::Rect(); } } else { _insetRect = celRect; } Ratio scaleX, scaleY; if (_scale.signal & kScaleSignalDoScaling32) { if (_scale.signal & kScaleSignalUseVanishingPoint) { int num = _scale.max * (_position.y - plane._vanishingPoint.y) / (scriptWidth - plane._vanishingPoint.y); scaleX = Ratio(num, 128); scaleY = Ratio(num, 128); } else { scaleX = Ratio(_scale.x, 128); scaleY = Ratio(_scale.y, 128); } } if (scaleX.getNumerator() && scaleY.getNumerator()) { _screenItemRect = _insetRect; const Ratio celToScreenX(screenWidth, celObj._scaledWidth); const Ratio celToScreenY(screenHeight, celObj._scaledHeight); // Cel may use a coordinate system that is not the same size as the // script coordinate system (usually this means high-resolution // pictures with low-resolution scripts) if (celObj._scaledWidth != kLowResX || celObj._scaledHeight != kLowResY) { // high resolution coordinates if (_useInsetRect) { const Ratio scriptToCelX(celObj._scaledWidth, scriptWidth); const Ratio scriptToCelY(celObj._scaledHeight, scriptHeight); mulru(_screenItemRect, scriptToCelX, scriptToCelY, 0); if (_screenItemRect.intersects(celRect)) { _screenItemRect.clip(celRect); } else { _screenItemRect = Common::Rect(); } } int displaceX = celObj._displace.x; int displaceY = celObj._displace.y; if (_mirrorX != celObj._mirrorX && _celInfo.type != kCelTypePic) { displaceX = celObj._width - celObj._displace.x - 1; } if (!scaleX.isOne() || !scaleY.isOne()) { // Different games use a different cel scaling mode, but the // difference isn't consistent across SCI versions; instead, // it seems to be related to an update that happened during // SCI2.1mid where games started using hi-resolution game // scripts if (scriptWidth == kLowResX) { mulinc(_screenItemRect, scaleX, scaleY); } else { _screenItemRect.left = (_screenItemRect.left * scaleX).toInt(); _screenItemRect.top = (_screenItemRect.top * scaleY).toInt(); if (scaleX.getNumerator() > scaleX.getDenominator()) { _screenItemRect.right = (_screenItemRect.right * scaleX).toInt(); } else { _screenItemRect.right = ((_screenItemRect.right - 1) * scaleX).toInt() + 1; } if (scaleY.getNumerator() > scaleY.getDenominator()) { _screenItemRect.bottom = (_screenItemRect.bottom * scaleY).toInt(); } else { _screenItemRect.bottom = ((_screenItemRect.bottom - 1) * scaleY).toInt() + 1; } } displaceX = (displaceX * scaleX).toInt(); displaceY = (displaceY * scaleY).toInt(); } mulinc(_screenItemRect, celToScreenX, celToScreenY); displaceX = (displaceX * celToScreenX).toInt(); displaceY = (displaceY * celToScreenY).toInt(); const Ratio scriptToScreenX = Ratio(screenWidth, scriptWidth); const Ratio scriptToScreenY = Ratio(screenHeight, scriptHeight); if (/* TODO: dword_C6288 */ false && _celInfo.type == kCelTypePic) { _scaledPosition.x = _position.x; _scaledPosition.y = _position.y; } else { _scaledPosition.x = (_position.x * scriptToScreenX).toInt() - displaceX; _scaledPosition.y = (_position.y * scriptToScreenY).toInt() - displaceY; } _screenItemRect.translate(_scaledPosition.x, _scaledPosition.y); if (_mirrorX != celObj._mirrorX && _celInfo.type == kCelTypePic) { Common::Rect temp(_insetRect); if (!scaleX.isOne()) { mulinc(temp, scaleX, Ratio()); } mulinc(temp, celToScreenX, Ratio()); CelObjPic *celObjPic = dynamic_cast<CelObjPic *>(_celObj); if (celObjPic == nullptr) { error("Expected a CelObjPic"); } temp.translate((celObjPic->_relativePosition.x * scriptToScreenX).toInt() - displaceX, 0); // TODO: This is weird. int deltaX = plane._planeRect.width() - temp.right - 1 - temp.left; _scaledPosition.x += deltaX; _screenItemRect.translate(deltaX, 0); } _scaledPosition.x += plane._planeRect.left; _scaledPosition.y += plane._planeRect.top; _screenItemRect.translate(plane._planeRect.left, plane._planeRect.top); _ratioX = scaleX * celToScreenX; _ratioY = scaleY * celToScreenY; } else { // low resolution coordinates int displaceX = celObj._displace.x; if (_mirrorX != celObj._mirrorX && _celInfo.type != kCelTypePic) { displaceX = celObj._width - celObj._displace.x - 1; } if (!scaleX.isOne() || !scaleY.isOne()) { mulinc(_screenItemRect, scaleX, scaleY); // TODO: This was in the original code, baked into the // multiplication though it is not immediately clear // why this is the only one that reduces the BR corner _screenItemRect.right -= 1; _screenItemRect.bottom -= 1; } _scaledPosition.x = _position.x - (displaceX * scaleX).toInt(); _scaledPosition.y = _position.y - (celObj._displace.y * scaleY).toInt(); _screenItemRect.translate(_scaledPosition.x, _scaledPosition.y); if (_mirrorX != celObj._mirrorX && _celInfo.type == kCelTypePic) { Common::Rect temp(_insetRect); if (!scaleX.isOne()) { mulinc(temp, scaleX, Ratio()); temp.right -= 1; } CelObjPic *celObjPic = dynamic_cast<CelObjPic *>(_celObj); if (celObjPic == nullptr) { error("Expected a CelObjPic"); } temp.translate(celObjPic->_relativePosition.x - (displaceX * scaleX).toInt(), celObjPic->_relativePosition.y - (celObj._displace.y * scaleY).toInt()); // TODO: This is weird. int deltaX = plane._gameRect.width() - temp.right - 1 - temp.left; _scaledPosition.x += deltaX; _screenItemRect.translate(deltaX, 0); } _scaledPosition.x += plane._gameRect.left; _scaledPosition.y += plane._gameRect.top; _screenItemRect.translate(plane._gameRect.left, plane._gameRect.top); if (celObj._scaledWidth != screenWidth || celObj._scaledHeight != screenHeight) { mulru(_scaledPosition, celToScreenX, celToScreenY); mulru(_screenItemRect, celToScreenX, celToScreenY, 1); } _ratioX = scaleX * celToScreenX; _ratioY = scaleY * celToScreenY; } _screenRect = _screenItemRect; if (_screenRect.intersects(plane._screenRect)) { _screenRect.clip(plane._screenRect); } else { _screenRect.right = 0; _screenRect.bottom = 0; _screenRect.left = 0; _screenRect.top = 0; } if (!_fixedPriority) { _priority = _z + _position.y; } } else { _screenRect.left = 0; _screenRect.top = 0; _screenRect.right = 0; _screenRect.bottom = 0; } }
Common::Rect ScreenItem::getNowSeenRect(const Plane &plane) const { CelObj &celObj = getCelObj(); Common::Rect celObjRect(celObj._width, celObj._height); Common::Rect nsRect; if (_useInsetRect) { if (_insetRect.intersects(celObjRect)) { nsRect = _insetRect; nsRect.clip(celObjRect); } else { nsRect = Common::Rect(); } } else { nsRect = celObjRect; } const uint16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth; const uint16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight; Ratio scaleX, scaleY; if (_scale.signal & kScaleSignalDoScaling32) { if (_scale.signal & kScaleSignalUseVanishingPoint) { int num = _scale.max * (_position.y - plane._vanishingPoint.y) / (scriptWidth - plane._vanishingPoint.y); scaleX = Ratio(num, 128); scaleY = Ratio(num, 128); } else { scaleX = Ratio(_scale.x, 128); scaleY = Ratio(_scale.y, 128); } } if (scaleX.getNumerator() == 0 || scaleY.getNumerator() == 0) { return Common::Rect(); } int16 displaceX = celObj._displace.x; int16 displaceY = celObj._displace.y; if (_mirrorX != celObj._mirrorX && _celInfo.type != kCelTypePic) { displaceX = celObj._width - displaceX - 1; } if (celObj._scaledWidth != kLowResX || celObj._scaledHeight != kLowResY) { // high resolution coordinates if (_useInsetRect) { Ratio scriptToCelX(celObj._scaledWidth, scriptWidth); Ratio scriptToCelY(celObj._scaledHeight, scriptHeight); mulru(nsRect, scriptToCelX, scriptToCelY, 0); if (nsRect.intersects(celObjRect)) { nsRect.clip(celObjRect); } else { nsRect = Common::Rect(); } } if (!scaleX.isOne() || !scaleY.isOne()) { // Different games use a different cel scaling mode, but the // difference isn't consistent across SCI versions; instead, // it seems to be related to an update that happened during // SCI2.1mid where games started using hi-resolution game // scripts if (scriptWidth == kLowResX) { mulinc(nsRect, scaleX, scaleY); // TODO: This was in the original code, baked into the // multiplication though it is not immediately clear // why this is the only one that reduces the BR corner nsRect.right -= 1; nsRect.bottom -= 1; } else { nsRect.left = (nsRect.left * scaleX).toInt(); nsRect.top = (nsRect.top * scaleY).toInt(); if (scaleX.getNumerator() > scaleX.getDenominator()) { nsRect.right = (nsRect.right * scaleX).toInt(); } else { nsRect.right = ((nsRect.right - 1) * scaleX).toInt() + 1; } if (scaleY.getNumerator() > scaleY.getDenominator()) { nsRect.bottom = (nsRect.bottom * scaleY).toInt(); } else { nsRect.bottom = ((nsRect.bottom - 1) * scaleY).toInt() + 1; } } } Ratio celToScriptX(scriptWidth, celObj._scaledWidth); Ratio celToScriptY(scriptHeight, celObj._scaledHeight); displaceX = (displaceX * scaleX * celToScriptX).toInt(); displaceY = (displaceY * scaleY * celToScriptY).toInt(); mulinc(nsRect, celToScriptX, celToScriptY); nsRect.translate(_position.x - displaceX, _position.y - displaceY); } else { // low resolution coordinates if (!scaleX.isOne() || !scaleY.isOne()) { mulinc(nsRect, scaleX, scaleY); // TODO: This was in the original code, baked into the // multiplication though it is not immediately clear // why this is the only one that reduces the BR corner nsRect.right -= 1; nsRect.bottom -= 1; } displaceX = (displaceX * scaleX).toInt(); displaceY = (displaceY * scaleY).toInt(); nsRect.translate(_position.x - displaceX, _position.y - displaceY); if (_mirrorX != celObj._mirrorX && _celInfo.type != kCelTypePic) { nsRect.translate(plane._gameRect.width() - nsRect.width(), 0); } } return nsRect; }
reg_t GfxText32::createFontBitmap(const CelInfo32 &celInfo, const Common::Rect &rect, const Common::String &text, const int16 foreColor, const int16 backColor, const GuiResourceId fontId, const int16 skipColor, const int16 borderColor, const bool dimmed, reg_t *outBitmapObject) { _field_22 = 0; _borderColor = borderColor; _text = text; _textRect = rect; _foreColor = foreColor; _dimmed = dimmed; setFont(fontId); int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth; int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight; int borderSize = 1; mulinc(_textRect, Ratio(_scaledWidth, scriptWidth), Ratio(_scaledHeight, scriptHeight)); CelObjView view(celInfo.resourceId, celInfo.loopNo, celInfo.celNo); _skipColor = view._transparentColor; _width = view._width * _scaledWidth / view._scaledWidth; _height = view._height * _scaledHeight / view._scaledHeight; Common::Rect bitmapRect(_width, _height); if (_textRect.intersects(bitmapRect)) { _textRect.clip(bitmapRect); } else { _textRect = Common::Rect(); } _bitmap = _segMan->allocateHunkEntry("FontBitmap()", _width * _height + CelObjMem::getBitmapHeaderSize()); byte *bitmap = _segMan->getHunkPointer(_bitmap); CelObjMem::buildBitmapHeader(bitmap, _width, _height, _skipColor, 0, 0, _scaledWidth, _scaledHeight, 0, false); Buffer buffer(_width, _height, bitmap + READ_SCI11ENDIAN_UINT32(bitmap + 28)); // NOTE: The engine filled the bitmap pixels with 11 here, which is silly // because then it just erased the bitmap using the skip color. So we don't // fill the bitmap redundantly here. _backColor = _skipColor; erase(bitmapRect, false); _backColor = backColor; view.draw(buffer, bitmapRect, Common::Point(0, 0), false, Ratio(_scaledWidth, view._scaledWidth), Ratio(_scaledHeight, view._scaledHeight)); if (_backColor != skipColor && _foreColor != skipColor) { erase(_textRect, false); } if (text.size() > 0) { if (_foreColor == skipColor) { error("TODO: Implement transparent text"); } else { if (borderColor != -1) { drawFrame(bitmapRect, borderSize, _borderColor, false); } drawTextBox(); } } *outBitmapObject = _bitmap; return _bitmap; }
Ratio ScrollWindow::where() const { return Ratio(_topVisibleLine, MAX(_numLines, 1)); }
void YScrollShape::draw(const DrawBuf &buf) const { MPane p(pane); if( !p ) return; Smooth::DrawArt art(buf); MPoint a=p.getBase(); MPoint s=p.getSize(); art.block(pane,+cfg.back); if( s.y<5*s.x ) return; MCoord x0=a.x; MCoord x1=x0+s.x; MCoord y0=a.y; MCoord y1=y0+s.x; MCoord y5=y0+s.y; MCoord y4=y5-s.x; bool enable_=enable; MCoord y2; MCoord y3; if( page>=total ) { enable_=false; y2=y1; y3=y4; } else { ulen cap=total-page; ulen pos_=Min(pos,cap); MCoord len=Max(Position(page,total,0,y4-y1),s.x); y2=Position(pos_,cap,y1,y4-len); y3=y2+len; } MCoord width=+cfg.width; MCoord d=Max<MCoord>(s.x/6,width); VColor top=+cfg.top; VColor bottom=+cfg.bottom; VColor face=+cfg.face; VColor faceUp=+cfg.faceUp; VColor topf=focus?+cfg.focus:top; VColor eface=enable_?face:bottom; // down if( down==ScrollType_Down ) { FigureBox fig_box(x0,x1,y0,y1); fig_box.solid(art,bottom); FigureUpArrow fig(x0+d,x1-d,y0+d,y1-d); fig.transform(Smooth::DotShift(MPoint::Diag(width))); fig.curveSolid(art,eface); } else { FigureTopBorder fig_top(x0,x1,y0,y1,width); fig_top.solid(art,topf); FigureBottomBorder fig_bottom(x0,x1,y0,y1,width); fig_bottom.solid(art,bottom); FigureUpArrow fig(x0+d,x1-d,y0+d,y1-d); VColor fc; if( enable_ ) { if( mover==ScrollType_Down ) fc=faceUp; else fc=face; } else { fc=bottom; } fig.curveSolid(art,fc); } // up if( down==ScrollType_Up ) { FigureBox fig_box(x0,x1,y4,y5); fig_box.solid(art,bottom); FigureDownArrow fig(x0+d,x1-d,y4+d,y5-d); fig.transform(Smooth::DotShift(MPoint::Diag(width))); fig.curveSolid(art,eface); } else { FigureTopBorder fig_top(x0,x1,y4,y5,width); fig_top.solid(art,topf); FigureBottomBorder fig_bottom(x0,x1,y4,y5,width); fig_bottom.solid(art,bottom); FigureDownArrow fig(x0+d,x1-d,y4+d,y5-d); VColor fc; if( enable_ ) { if( mover==ScrollType_Up ) fc=faceUp; else fc=face; } else { fc=bottom; } fig.curveSolid(art,fc); } // down page { FigureBox fig_top(x0,x0+width,y1,y2); fig_top.solid(art,topf); FigureBox fig_bottom(x1-width,x1,y1,y2); fig_bottom.solid(art,bottom); } if( down==ScrollType_DownPage ) { MCoord e=Ratio(427,10)*s.x; FigureBox fig(x0+e,x1-e,y1,y2); fig.solid(art,face); } else { MCoord e=Ratio(3,3)*s.x; FigureBox fig(x0+e,x1-e,y1,y2); VColor fc; if( enable_ ) { if( mover==ScrollType_DownPage ) fc=faceUp; else fc=face; } else { fc=bottom; } fig.solid(art,fc); } // up page { FigureBox fig_top(x0,x0+width,y3,y4); fig_top.solid(art,topf); FigureBox fig_bottom(x1-width,x1,y3,y4); fig_bottom.solid(art,bottom); } if( down==ScrollType_UpPage ) { MCoord e=Ratio(427,10)*s.x; FigureBox fig(x0+e,x1-e,y3,y4); fig.solid(art,face); } else { MCoord e=Ratio(3,3)*s.x; FigureBox fig(x0+e,x1-e,y3,y4); VColor fc; if( enable_ ) { if( mover==ScrollType_UpPage ) fc=faceUp; else fc=face; } else { fc=bottom; } fig.solid(art,fc); } // drag { FigureBox fig(x0,x1,y2,y3); fig.solid(art,TwoField({x0,y0},top,{x1,y0},bottom)); } { MCoord e=s.x/3; MCoord a0=x0+e; MCoord a1=x0+s.x/2; MCoord a2=x1-e; MCoord f=(y3-y2)/4; MCoord b0=y2+f; MCoord b1=y2+(y3-y2)/2; MCoord b2=y3-f; VColor fc; if( enable_ ) { if( mover==ScrollType_Drag ) fc=faceUp; else fc=face; } else { fc=bottom; } if( b2-b0>2*(a2-a0) ) { MCoord c=(b2-b0)/2-(a2-a0); FigurePoints<6> fig; fig[0]={a0,b1-c}; fig[1]={a1,b0}; fig[2]={a2,b1-c}; fig[3]={a2,b1+c}; fig[4]={a1,b2}; fig[5]={a0,b1+c}; fig.solid(art,fc); } else { FigurePoints<4> fig; fig[0]={a0,b1}; fig[1]={a1,b0}; fig[2]={a2,b1}; fig[3]={a1,b2}; fig.solid(art,fc); } } }
Common::Rect GfxText32::getTextSize(const Common::String &text, int16 maxWidth, bool doScaling) { // NOTE: Like most of the text rendering code, this function was pretty // weird in the original engine. The initial result rectangle was actually // a 1x1 rectangle (0, 0, 0, 0), which was then "fixed" after the main // text size loop finished running by subtracting 1 from the right and // bottom edges. Common::Rect result; int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth; int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight; maxWidth = maxWidth * _scaledWidth / scriptWidth; _text = text; if (maxWidth >= 0) { if (maxWidth == 0) { // TODO: This was hardcoded to 192, but guessing // that it was originally 60% of the scriptWidth // before the compiler took over. // Verify this by looking at a game that uses a // scriptWidth other than 320, like LSL7 maxWidth = _scaledWidth * (scriptWidth * 0.6) / scriptWidth; } result.right = maxWidth; int16 textWidth = 0; if (_text.size() > 0) { const char *rawText = _text.c_str(); const char *sourceText = rawText; uint charIndex = 0; uint nextCharIndex = 0; while (*rawText != '\0') { uint length = getLongest(&nextCharIndex, result.width()); textWidth = MAX(textWidth, getTextWidth(charIndex, length)); charIndex = nextCharIndex; rawText = sourceText + charIndex; // TODO: Due to getLongest and getTextWidth not having side // effects, it is possible that the currently loaded font's // height is wrong for this line if it was changed inline result.bottom += _font->getHeight(); } } if (textWidth < maxWidth) { result.right = textWidth; } } else { result.right = getTextWidth(0, 10000); result.bottom = _font->getHeight() + 1; } if (doScaling) { // NOTE: The original code did some more complex stuff for edge // rounding. The right edge was designed to always round down, // and the bottom edge was designed to always round up. It seems // we are able to get away with simpler rounding, but it is // possible that there are still some edge cases here. mul(result, Ratio(scriptWidth, _scaledWidth), Ratio(scriptHeight, _scaledHeight)); result.right += 1; result.bottom += 1; } return result; }
void CastRelation() { char ignoreT[objMax]; int i, saveRev; real ratio, t1, t2, t; real ppowerT[oNormOpt+1]; /* Cast the first chart. */ ciMain = ciCore; if (us.fRelocation && us.nRel == rcComposite) { OO=us.lonDef; AA=us.latDef ; NN=us.altDef; } t1 = CastChart(fTrue); cp1 = cp0; saveRev = hRevers; if (us.nRel == rcTransit || us.nRel == rcProgress) for (i = 1; i <= cObjOpt; i++) { cp1.dir[i] = 0.0; if (i > oNormOpt) continue; cp1.altdir[i] = 0.0; } #ifdef GRAPH /* Struct GS is defined with graphics. */ if (!gs.nAnim) { #endif if (!FCreateGrid(fFalse)) return; PlanetPPower(); #ifdef GRAPH } #endif /* Cast the second chart. */ ciCore = ciTwin; if (us.nRel == rcTransit) { for (i = 0; i <= cObjOpt; i++) { ignoreT[i] = ignore[i]; if (us.fSector || us.fAstroGraph) ignore[i] = ignore[i] && ignore2[i]; else ignore[i] = ignore2[i]; } } else if (us.nRel == rcProgress) { us.fProgress = fTrue; is.JDp = MdytszToJulian(MM, DD, YY, TT, SS, ZZ)-rRound; ciCore = ciMain; for (i = 0; i <= cObjOpt; i++) { ignoreT[i] = ignore[i]; if (us.fSector || us.fAstroGraph) ignore[i] = ignore[i] && ignore3[i]; else ignore[i] = ignore3[i]; } } if (us.fRelocation && us.nRel == rcComposite) { OO=us.lonDef; AA=us.latDef ; NN=us.altDef; } t2 = CastChart(fTrue); if (us.nRel == rcTransit) { for (i = 0; i <= cObjOpt; i++) { ignore2[i] = ignore[i]; ignore[i] = ignoreT[i]; } } else if (us.nRel == rcProgress) { us.fProgress = fFalse; for (i = 0; i <= cObjOpt; i++) { ignore3[i] = ignore[i]; ignore[i] = ignoreT[i]; } } cp2 = cp0; if (us.nRel == rcDual) { if (!FCreateGrid(fFalse)) return; for (i = 0; i <= oNormOpt; i++) ppowerT[i] = ppower1[i]; PlanetPPower(); for (i = 0; i <= oNormOpt; i++) { ppower2[i] = ppower1[i]; ppower1[i] = ppowerT[i]; } } hRevers = saveRev; ciCore = ciMain; /* Now combine the two charts based on what relation we are doing. */ /* For the standard -r synastry chart, use the house cusps of chart1 */ /* and the planets positions of chart2. */ ratio = (real)us.nRatio1 / ((real)(us.nRatio1 + us.nRatio2)); if (us.nRel <= rcSynastry) { for (i = 1; i <= cSign; i++) chouse[i] = cp1.cusp[i]; /* For the -rc composite chart, take the midpoints of the planets/houses. */ } else if (us.nRel == rcComposite) { if (fProgressRatio) { ratio=(MdytszToJulian(ciThre.mon,ciThre.day,ciThre.yea,ciThre.tim,ciThre.dst,ciThre.zon)- Min(MdytszToJulian(Mon, Day, Yea, Tim, Dst, Zon), MdytszToJulian(ciTwin.mon,ciTwin.day,ciTwin.yea,ciTwin.tim,ciTwin.dst,ciTwin.zon)))/ RAbs(MdytszToJulian(Mon, Day, Yea, Tim, Dst, Zon)- MdytszToJulian(ciTwin.mon,ciTwin.day,ciTwin.yea,ciTwin.tim,ciTwin.dst,ciTwin.zon)); } for (i = 0; i <= cObjOpt; i++) { planet[i] = Ratio(cp1.obj[i], cp2.obj[i], ratio); if (RAbs(cp2.obj[i] - cp1.obj[i]) > rDegHalf) planet[i] = Mod(planet[i] + rDegMax*ratio); planetalt[i] = Ratio(cp1.alt[i], cp2.alt[i], ratio); ret[i] = Ratio(cp1.dir[i], cp2.dir[i], ratio); altret[i] = Ratio(cp1.altdir[i], cp2.altdir[i], ratio); planetdis[i] = Ratio(cp1.dis[i], cp2.dis[i], ratio); disret[i] = Ratio(cp1.disdir[i], cp2.disdir[i], ratio); } for (i = 1; i <= cSign; i++) { chouse[i] = Ratio(cp1.cusp[i], cp2.cusp[i], ratio); if (RAbs(cp2.cusp[i] - cp1.cusp[i]) > rDegHalf) chouse[i] = Mod(chouse[i] + rDegMax*ratio); } /* Make sure we don't have any 180 degree errors in house cusp */ /* complement pairs, which may happen if the cusps are far apart. */ for (i = 1; i <= cSign; i++) if (MinDistance(chouse[sCap], Mod(chouse[i]-ZFromS(i+3))) > rDegQuad) chouse[i] = Mod(chouse[i]+rDegHalf); for (i = 1; i <= cSign; i++) if (RAbs(MinDistance(chouse[i], planet[oAsc - 1 + i])) > rDegQuad) planet[oAsc - 1 + i] = Mod(planet[oAsc - 1 + i]+rDegHalf); ciMain.loc=""; if (!us.fGraphics) ciMain.nam=strdup(strcat(strcat(ciMain.nam," and "),ciTwin.nam)); /* For the -rm time space midpoint chart, calculate the midpoint time and */ /* place between the two charts and then recast for the new chart info. */ } else if (us.nRel == rcMidpoint) { if (!is.fDavison) { is.T = Ratio(t1, t2, ratio); t = (is.T*36525.0)+rRound; is.JD = RFloor(t)+2415020.0; TT = RFract(t)*24.0; /* ZZ = Ratio(DecToDeg(Zon), DecToDeg(ciTwin.zon), ratio); SS = Ratio(DecToDeg(Dst), DecToDeg(ciTwin.dst), ratio); TT -= ZZ - SS; if (TT < 0.0) { TT += 24.0; is.JD -= 1.0; } if (TT >= 24.0) { TT -= 24.0; is.JD += 1.0; }*/ JulianToMdy(is.JD, &MM, &DD, &YY); OO = Ratio(DecToDeg(Lon), DecToDeg(ciTwin.lon), ratio); if (RAbs(ciTwin.lon-Lon) > rDegHalf) OO = Mod(OO+rDegMax*ratio); AA = Ratio(DecToDeg(Lat), DecToDeg(ciTwin.lat), ratio); NN = Ratio(DecToDeg(Alt), DecToDeg(ciTwin.alt), ratio); TT = DegToDec(TT); SS=ZZ=0.0; /*SS = DegToDec(SS); ZZ = DegToDec(ZZ);*/ OO = DegToDec(OO); AA = DegToDec(AA); ciCore.loc=""; if (!us.fGraphics) ciCore.nam=strdup(strcat(strcat(ciMain.nam," and "),ciTwin.nam)); ciMain = ciCore; } else is.T=t1; CastChart(fFalse); is.fDavison=fTrue; /* There are a couple of non-astrological charts, which only require the */ /* number of days that have passed between the two charts to be done. */ } else is.JD = RAbs(t2-t1)*36525.0; ComputeInHouses(); }