BPicture: Fix archive constructor.
[haiku.git] / src / add-ons / accelerants / ati / mach64_util.cpp
blobd7ac5f359d0a27641a50e35e1f988d4ec3928415
1 /*
2 Haiku ATI video driver adapted from the X.org ATI driver.
4 Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
6 Copyright 2009 Haiku, Inc. All rights reserved.
7 Distributed under the terms of the MIT license.
9 Authors:
10 Gerald Zajac 2009
13 #include "accelerant.h"
14 #include "mach64.h"
17 #define MAX_INT ((int)((unsigned int)(-1) >> 2))
21 void
22 Mach64_ReduceRatio(int *numerator, int *denominator)
24 // Reduce a fraction by factoring out the largest common divider of the
25 // fraction's numerator and denominator.
27 int multiplier = *numerator;
28 int divider = *denominator;
29 int remainder;
31 while ((remainder = multiplier % divider)) {
32 multiplier = divider;
33 divider = remainder;
36 *numerator /= divider;
37 *denominator /= divider;
42 int
43 Mach64_Divide(int numerator, int denominator, int shift, const int roundingKind)
45 // Using integer arithmetic and avoiding overflows, this function finds the
46 // rounded integer that best approximates
48 // numerator shift
49 // ----------- * 2
50 // denominator
52 // using the specified rounding (floor (<0), nearest (=0) or ceiling (>0)).
54 Mach64_ReduceRatio(&numerator, &denominator);
56 // Deal with left shifts but try to keep the denominator even.
57 if (denominator & 1) {
58 if (denominator <= MAX_INT) {
59 denominator <<= 1;
60 shift++;
62 } else {
63 while ((shift > 0) && !(denominator & 3)) {
64 denominator >>= 1;
65 shift--;
69 // Deal with right shifts.
70 while (shift < 0) {
71 if ((numerator & 1) && (denominator <= MAX_INT))
72 denominator <<= 1;
73 else
74 numerator >>= 1;
76 shift++;
79 int rounding = 0; // Default to floor
81 if (!roundingKind) // nearest
82 rounding = denominator >> 1;
83 else if (roundingKind > 0) // ceiling
84 rounding = denominator - 1;
86 return ((numerator / denominator) << shift) +
87 ((((numerator % denominator) << shift) + rounding) / denominator);