Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
Ratio DrawLab::Zoom(Coord delta)
 {
  if( delta>0 )
    {
     return Ratio(17,4).pow(delta); 
    }
  else
    {
     return Ratio(15,4).pow(-delta);
    }
 }
Ejemplo n.º 5
0
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);
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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);
}
Ejemplo n.º 8
0
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)));
}
Ejemplo n.º 9
0
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));
}
Ejemplo n.º 10
0
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");
}
Ejemplo n.º 12
0
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();
}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
0
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();
    }
}
Ejemplo n.º 15
0
//------------------------------------------------------------------------------
// 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));
}
Ejemplo n.º 16
0
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);
}
Ejemplo n.º 18
0
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);
}
Ejemplo n.º 20
0
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.";
}
Ejemplo n.º 21
0
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;
}
Ejemplo n.º 22
0
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;
	}
}
Ejemplo n.º 23
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;
}
Ejemplo n.º 24
0
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;
}
Ejemplo n.º 25
0
Ratio ScrollWindow::where() const {
	return Ratio(_topVisibleLine, MAX(_numLines, 1));
}
Ejemplo n.º 26
0
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);
     }
  }
 }
Ejemplo n.º 27
0
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;
}
Ejemplo n.º 28
0
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();
}