This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/11910] New: inline assembler causes compiler error
- From: "paradox at bbhc dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 13 Aug 2003 23:57:16 -0000
- Subject: [Bug c++/11910] New: inline assembler causes compiler error
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11910
Summary: inline assembler causes compiler error
Product: gcc
Version: 3.2
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: paradox at bbhc dot org
CC: gcc-bugs at gcc dot gnu dot org
gcc -c -ffreestanding -fno-rtti -fno-exceptions -fno-builtin -nostdlib -
Iinclude out/surface.o modules/aqua/surface.cpp
Reading specs from ../lib/gcc-lib/mingw32/3.2/specs
Configured with: ../gcc/configure --with-gcc --with-gnu-ld --with-gnu-as --
host=
mingw32 --target=mingw32 --prefix=/mingw --enable-threads --disable-nls --
enable
-languages=f77,c++,objc,ada --disable-win32-registry --disable-shared
Thread model: win32
gcc version 3.2 (mingw special 20020817-1)
Windows XP Professional
Internal compiler error in instantiate_virtual_regs_1 at function.c:3972
Apparently the inline asm causes some sort of error. Anything else I can
include that would be helpful, let me know.ex
--- preprocessed source ---
# 1 "modules/aqua/surface.cpp"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "modules/aqua/surface.cpp"
# 1 "include/aqua/surface.h" 1
# 1 "include/d_types.h" 1
# 17 "include/d_types.h"
typedef long long octa;
typedef long tetra;
typedef short wyde;
typedef char byte;
typedef unsigned long long octa_u;
typedef unsigned long tetra_u;
typedef unsigned short wyde_u;
typedef unsigned char byte_u;
# 5 "include/aqua/surface.h" 2
# 1 "include/lib/geom/g_rect.h" 1
# 27 "include/lib/geom/g_rect.h"
# 1 "include/lib/geom/g_segment.h" 1
# 22 "include/lib/geom/g_segment.h"
# 1 "include/lib/geom/g_point.h" 1
# 23 "include/lib/geom/g_point.h"
namespace dosadi
{
namespace geom
{
# 39 "include/lib/geom/g_point.h"
class gPoint
{
public:
float x, y;
gPoint () {}
gPoint (float ix, float iy) : x(ix), y(iy) {}
gPoint (const gPoint ©) : x(copy.x), y(copy.y) {}
virtual ~gPoint () {}
};
};
};
# 23 "include/lib/geom/g_segment.h" 2
namespace dosadi
{
namespace geom
{
# 40 "include/lib/geom/g_segment.h"
class gSegment
{
public:
gPoint start, end;
gSegment () {}
gSegment (float ix, float iy, float ix2, float iy2) : start
(ix, iy), end(ix2, iy2) {}
gSegment (const gSegment ©) : start(copy.start), end
(copy.end) {}
virtual ~gSegment () {}
void Start(float x, float y) { start.x=x; start.y=y; }
void End(float x, float y) { end.x=x; end.y=y; }
};
};
};
# 28 "include/lib/geom/g_rect.h" 2
namespace dosadi
{
namespace geom
{
# 66 "include/lib/geom/g_rect.h"
class gRect
{
public:
float xmin, ymin, xmax, ymax;
gRect ();
gRect (float ixmin, float iymin, float ixmax, float iymax);
gRect (const gRect ©);
virtual ~gRect ();
void intersect (float ixmin, float iymin, float ixmax, float iymax);
inline void intersect (const gRect &other)
{ intersect (other.xmin, other.ymin, other.xmax, other.ymax); }
bool intersects (const gRect &target) const;
void Union (float ixmin, float iymin, float ixmax, float iymax);
inline void Union (const gRect &other)
{ Union (other.xmin, other.ymin, other.xmax, other.ymax); }
void Exclude (float ixmin, float iymin, float ixmax, float iymax);
inline void Exclude (const gRect &other)
{ Exclude (other.xmin, other.ymin, other.xmax, other.ymax); }
void Subtract (const gRect &rect);
inline bool IsEmpty () const
{ return (xmin >= xmax) || (ymin >= ymax); }
inline void MakeEmpty ()
{ xmin = xmax = 0; }
inline void Set (float ixmin, float iymin, float ixmax, float iymax)
{
xmin = ixmin; xmax = ixmax;
ymin = iymin; ymax = iymax;
}
inline void Set (const gRect &target)
{
xmin = target.xmin; xmax = target.xmax;
ymin = target.ymin; ymax = target.ymax;
}
inline void SetPos (float x, float y)
{ xmin = x; ymin = y; }
inline void SetSize (float w, float h)
{ xmax = xmin + w; ymax = ymin + h; }
inline void Move (float dX, float dY)
{ xmin += dX; xmax += dX; ymin += dY; ymax += dY; }
inline float Width () const { return xmax - xmin; }
inline float Height () const { return ymax - ymin; }
inline bool Contains (float x, float y) const
{ return (x >= xmin) && (x < xmax) && (y >= ymin) && (y < ymax); }
inline bool ContainsRel (float x, float y) const
{ return (x >= 0) && (x < Width ()) && (y >= 0) && (y < Height ()); }
inline bool Equal (float ixmin, float iymin, float ixmax, float iymax) const
{ return (xmin == ixmin) && (ymin == iymin) &&
(xmax == ixmax) && (ymax == iymax); }
inline bool Equal (const gRect &other) const
{ return Equal (other.xmin, other.ymin, other.xmax, other.ymax); }
inline void Normalize ()
{
if (xmin > xmax) { float tmp = xmin; xmin = xmax; xmax = tmp; }
if (ymin > ymax) { float tmp = ymin; ymin = ymax; ymax = tmp; }
}
inline float Area () const
{
if (IsEmpty ())
return 0;
else
return Width () * Height ();
}
void AddAdjanced (const gRect &rect);
inline bool operator == (const gRect& rect) const
{
return Equal (rect);
}
inline bool operator != (const gRect &rect) const
{
return !Equal (rect);
}
inline void Extend (float x, float y)
{
if (xmin > x) xmin = x; if (xmax < x) xmax = x;
if (ymin > y) ymin = y; if (ymax < y) ymax = y;
}
inline void Minimum(const gRect& rect)
{
if (Width()>rect.Width())
xmax = xmin+rect.Width();
if (Height()>rect.Height())
ymax = ymin+rect.Height();
}
inline void Maximum(const gRect& rect)
{
if (Width()<rect.Width())
xmax = xmin+rect.Width();
if (Height()<rect.Height())
ymax = ymin+rect.Height();
}
void Join (const gRect &rect);
void Outset(float n);
void Inset(float n);
# 254 "include/lib/geom/g_rect.h"
bool ClipLineGeneral (float& x1, float& y1, float& x2, float& y2);
# 263 "include/lib/geom/g_rect.h"
bool ClipLine (float& x1, float& y1, float& x2, float& y2);
# 272 "include/lib/geom/g_rect.h"
bool ClipLineSafe (float& x1, float& y1, float& x2, float& y2);
# 281 "include/lib/geom/g_rect.h"
bool ClipLineSafe (gSegment &seg) { ClipLineSafe(seg.start.x, seg.start.y,
seg.end.x, seg.end.y); }
};
};
};
# 6 "include/aqua/surface.h" 2
# 1 "include/lib/geom/g_clip.h" 1
# 1 "include/lib/geom/g_rect_region.h" 1
# 31 "include/lib/geom/g_rect_region.h"
namespace dosadi
{
namespace geom
{
const int FRAGMENT_BUFFER_SIZE=64;
# 50 "include/lib/geom/g_rect_region.h"
class gRectRegion
{
protected:
gRect* region;
int region_count;
int region_max;
gRect fragment[FRAGMENT_BUFFER_SIZE];
int gather_mark;
void pushRect(gRect const &);
void deleteRect(int);
void fragmentRect(gRect&, gRect&, int mode);
void nkSplit(gRect& r1, gRect& r2);
void fragmentContainedRect(gRect &r1, gRect &r2);
void markForGather();
void gatherFragments();
public:
gRectRegion();
gRectRegion(const gRectRegion ®ion);
~gRectRegion();
void Include(const gRect &rect);
void Exclude(const gRect &rect);
void ClipTo(gRect &clip);
int Count() const { return region_count; }
gRect& RectAt(int i) const { return region[i]; }
bool Contains (float x, float y);
void makeEmpty();
void Copy(const gRectRegion ®ion);
};
};
};
# 7 "include/lib/geom/g_clip.h" 2
# 1 "include/lib/containers/c_vector.h" 1
# 1 "include/lib/dosadi_libc/stddef.h" 1
# 22 "include/lib/dosadi_libc/stddef.h"
typedef unsigned int size_t;
typedef size_t size_type;
# 5 "include/lib/containers/c_vector.h" 2
# 1 "include/lib/dosadi_libc/string.h" 1
# 44 "include/lib/dosadi_libc/string.h"
extern "C" {
extern void *malloc(size_t size);
extern void free(void *p);
size_t _dosadi_libc_strlen(const char *s);
size_t _dosadi_libc_wstrlen(const wchar_t *s);
size_t _dosadi_libc_strnlen(const char *s, size_t maxlen);
size_t _dosadi_libc_wstrnlen(const wchar_t *s, size_t maxlen);
int _dosadi_libc_strcmp(const char *s1, const char *s2);
int _dosadi_libc_strncmp(const char *s1, const char *s2, size_t size);
char *_dosadi_libc_strcpy(char *s1, const char *s2);
char *_dosadi_libc_wcscpy(wchar_t *s1, const wchar_t *s2);
char *_dosadi_libc_strncpy(char *s1, const char *s2, size_t size);
char *_dosadi_libc_wcsncpy(wchar_t *s1, const wchar_t *s2, size_t size);
char *_dosadi_libc_strpncpy(char *s1, char *s2, size_t size);
char *_dosadi_libc_wcspncpy(char *s1, char *s2, size_t size);
char *_dosadi_libc_strpcpy(char *s1, char *s2);
char *_dosadi_libc_wcspcpy(char *s1, char *s2);
char *_dosadi_libc_strstr(const char *haystack, const char *needle);
wchar_t *_dosadi_libc_wstrstr(const wchar_t *haystack, const wchar_t *needle);
size_t _dosadi_libc_strspn(const char *string, const char *skipset);
size_t _dosadi_libc_strcspn(const char *string, const char *stopset);
char * _dosadi_libc_strpbrk(const char *string, const char *stopset);
char *_dosadi_libc_strchr(const char *string, int c);
char *_dosadi_libc_strrchr(const char *string, int c, size_t size);
char *_dosadi_libc_strchrnul(const char *string, int c);
char *_dosadi_libc_strrchrnul(const char *string, int c, size_t size);
void *_dosadi_libc_memmem(const void *haystack, size_t haystack_size, const
void *needle, size_t needle_size);
void *_dosadi_libc_memcpy(void *to, const void *from, size_t size);
void *_dosadi_libc_wmemcpy(wchar_t *to, const wchar_t *from, size_t size);
void *_dosadi_libc_mempcpy(void *to, const void *from, size_t size);
void *_dosadi_libc_wmempcpy(wchar_t *to, const wchar_t *from, size_t size);
void *_dosadi_libc_memmove(void *to, const void *from, size_t size);
void *_dosadi_libc_wmemmove(void *to, const void *from, size_t size);
void *_dosadi_libc_memccpy(void *to, void *from, int c, size_t size);
void *_dosadi_libc_wmemccpy(void *to, void *from, int c, size_t size);
void *_dosadi_libc_memset(void *block, int c, size_t size);
wchar_t *_dosadi_libc_wmemset(wchar_t *block, int c, size_t size);
int _dosadi_libc_memcmp(const void *a1, const void *a2, size_t size);
};
static inline char *strdup(const char *s)
{
size_t size = _dosadi_libc_strlen(s)+1;
char *s2 = (char *)malloc(size);
if (!s2) return 0;
else return (char *)_dosadi_libc_memcpy(s2, s, size);
}
static inline char *wcsdup(const wchar_t *s)
{
size_t size = (_dosadi_libc_wstrlen(s)<<1)+2;
wchar_t *s2 = (wchar_t *)malloc(size);
if (!s2) return 0;
else return (char *)_dosadi_libc_wmemcpy(s2, s, size>>1);
}
static inline char *strndup(const char *s, size_t max)
{
size_t size = _dosadi_libc_strlen(s)+1;
size_t sl = (max < size ? max+1 : size);
char *s2 = (char *)malloc(sl);
if (!s2) return 0;
else
{
_dosadi_libc_memcpy(s2, s, sl-1);
s2[sl]=0;
return s2;
}
}
# 274 "include/lib/dosadi_libc/string.h"
static inline char *strncat (char *to, const char *from, size_t size)
{
to[_dosadi_libc_strlen(to) + size] = '\0';
_dosadi_libc_strncpy (to + _dosadi_libc_strlen(to), from, size);
return to;
}
# 288 "include/lib/dosadi_libc/string.h"
static inline wchar_t *wcsncat (wchar_t *wto, const wchar_t *wfrom, size_t
size)
{
wto[_dosadi_libc_wstrlen (wto) + size] = L'\0';
_dosadi_libc_wcsncpy (wto + _dosadi_libc_wstrlen (wto), wfrom, size);
return wto;
}
# 6 "include/lib/containers/c_vector.h" 2
namespace dosadi
{
namespace container {
const size_type vector_grow_delta = 16;
# 22 "include/lib/containers/c_vector.h"
template <class T>
class vector
{
private:
int buffer_size,
stack_top;
T *buffer;
public:
vector ():buffer_size(0), stack_top(0), buffer(0)
{
}
vector (vector<T> &v){
buffer_size = v.buffer_size;
stack_top = v.stack_top;
buffer = new T[buffer_size];
_dosadi_libc_memcpy(buffer, v.buffer, stack_top*sizeof
(T));
}
~vector()
{
if (buffer) delete [] buffer;
}
size_type size() const { return stack_top; }
size_type max_size() const { return 1<<30; }
void resize(size_type new_size)
{
if (new_size==buffer_size) return;
T *nb = new T[new_size];
if (new_size<buffer_size && buffer!=0)
{
_dosadi_libc_memcpy(nb, buffer,
new_size*sizeof(T));
buffer_size=new_size;
if (stack_top>buffer_size)
stack_top=buffer_size;
}
else if (buffer!=0)
{
_dosadi_libc_memcpy(nb, buffer,
stack_top*sizeof(T));
buffer_size=new_size;
}
else
{
buffer_size=new_size;
}
delete [] buffer;
buffer = nb;
}
size_type capacity() const { return buffer_size; }
# 106 "include/lib/containers/c_vector.h"
void reserve(size_type n)
{
if (n<buffer_size) return;
resize(n);
}
bool empty() const
{
return stack_top == 0;
}
void pop_back()
{
if (stack_top>0) --stack_top;
}
void erase(size_type i)
{
if (i>=stack_top) return;
if (i==stack_top-1) { pop_back(); return; }
T *tmp = &buffer[i];
T *tmp2 = &buffer[i+i];
_dosadi_libc_memcpy(tmp, tmp2, (size()-i-1) *
sizeof(T));
--stack_top;
}
void push_back(const T& x)
{
if (stack_top >= buffer_size)
reserve(buffer_size+vector_grow_delta);
buffer[stack_top++] = x;
}
void clear()
{
stack_top = 0;
}
T& front()
{
return buffer[0];
}
T& back()
{
return buffer[stack_top-1];
}
size_type begin()
{ return 0; }
size_type end()
{ return stack_top; }
size_type find(const T& x)
{
for(size_type i=begin(); i<end(); ++i)
{
if (buffer[i] == x)
return i;
}
return end();
}
T& at(size_type i)
{
return buffer[i];
}
T& operator[](size_type i)
{
return buffer[i];
}
vector<T>& operator=(const vector<T> &b)
{
if (buffer)
delete [] buffer;
buffer_size = b.buffer_size;
stack_top = b.stack_top;
buffer = new T[buffer_size];
_dosadi_libc_memcpy(buffer, b.buffer,
b.stack_top*sizeof(T));
return *this;
}
};
};
};
# 11 "include/lib/geom/g_clip.h" 2
namespace dosadi
{
namespace geom
{
class gClippingRegion
{
gRectRegion clip_region;
gRect clip_bounds;
public:
gClippingRegion(tetra_u w, tetra_u h): clip_bounds(0,
0, w, h)
{
}
~gClippingRegion()
{
}
void Include(gRect &rect);
void Exclude(gRect &rect);
void Set(float xmin, float ymin, float xmax, float
ymax)
{ clip_bounds.Set(xmin, ymin, xmax, ymax); }
bool Contains(float x, float y) { return Contains
(gPoint(x,y)); }
bool Contains(gPoint p);
container::vector<gSegment>
SegmentLine(gSegment &seg);
container::vector<gRect>
SegmentRect(gRect &rect);
};
};
};
# 7 "include/aqua/surface.h" 2
namespace dosadi
{
namespace Aqua
{
const byte_u PEN_COPY = 0;
const byte_u PEN_ALPHA_AVG = 1;
const byte_u PEN_ALPHA_SRC = 2;
const byte_u PEN_ALPHA_DST = 3;
const byte_u PEN_XOR = 4;
const byte_u PEN_AND = 5;
const byte_u PEN_OR = 6;
const byte_u PEN_RUB = 7;
const byte_u PEN_RUB_MAP = 8;
const byte_u PEN_ADD = 9;
const byte_u PEN_SUB = 10;
const byte_u CURVE_QUAD_UL = 0;
const byte_u CURVE_QUAD_LL = 1;
const byte_u CURVE_QUAD_UR = 2;
const byte_u CURVE_QUAD_LR = 3;
union Pixel
{
struct color_component
{
byte_u r,
g,
b,
a;
} b;
tetra_u t;
Pixel() {};
Pixel(tetra_u c):t(c) {}
Pixel(byte_u _r, byte_u _g, byte_u _b, byte_u _a)
{ b.r =_r; b.g=_g; b.b=_b; b.a=_a; }
Pixel(Pixel &c):t(c.t) {}
};
class Surface
{
Pixel *surf;
Surface *rub_surf;
tetra_u width,
height;
byte_u pen_mode;
geom::gRect clip;
public:
Surface();
~Surface();
Surface(tetra_u w, tetra_u h);
# 101 "include/aqua/surface.h"
bool Create(tetra_u w, tetra_u h);
bool isEmpty() { return surf==0; }
void Select(Surface *rub);
geom::gRect getClip()
{ return clip; }
void setClip(const geom::gRect &r);
tetra_u Width() { return width; }
tetra_u Height() { return height; }
public:
void Clear(Pixel c);
# 147 "include/aqua/surface.h"
bool getPixel(float x, float y, Pixel &c);
# 159 "include/aqua/surface.h"
bool getMappedPixel(float x, float y, float w, float
h, Pixel &c);
# 169 "include/aqua/surface.h"
bool getTiledPixel(float x, float y, Pixel &c);
# 178 "include/aqua/surface.h"
bool putPixel(float x, float y, const Pixel &c);
# 188 "include/aqua/surface.h"
void drawHLine(float x, float y, float w, const Pixel
&c);
# 198 "include/aqua/surface.h"
void drawVLine(float x, float y, float h, const Pixel
&c);
# 207 "include/aqua/surface.h"
void drawLine(const geom::gRect &r, const Pixel &c);
# 216 "include/aqua/surface.h"
void drawRect(const geom::gRect &r, const Pixel &c);
# 225 "include/aqua/surface.h"
void fillRect(const geom::gRect &r, const Pixel &c);
# 235 "include/aqua/surface.h"
void drawCircle(const geom::gRect &r, const Pixel &c);
# 245 "include/aqua/surface.h"
void fillCircle(const geom::gRect &r, const Pixel &c);
# 255 "include/aqua/surface.h"
void drawEllipse(const geom::gRect &r, const Pixel &c);
# 265 "include/aqua/surface.h"
void fillEllipse(const geom::gRect &r, const Pixel &c);
# 276 "include/aqua/surface.h"
void drawQuarterCircle(const geom::gRect &r, byte_u
quadrant, const Pixel &c);
# 287 "include/aqua/surface.h"
void fillQuarterCircle(const geom::gRect &r, byte_u
quadrant, const Pixel &c);
# 298 "include/aqua/surface.h"
void drawQuarterEllipse(const geom::gRect &r, byte_u
quadrant, const Pixel &c);
# 309 "include/aqua/surface.h"
void fillQuarterEllipse(const geom::gRect &r, byte_u
quadrant, const Pixel &c);
# 321 "include/aqua/surface.h"
void blitSurface(Surface &s, const geom::gRect &src,
const geom::gRect &dst);
# 334 "include/aqua/surface.h"
void blitMaskedSurface(Surface &s, const geom::gRect
&src, const geom::gRect &dst, const Pixel &c);
};
};
};
# 2 "modules/aqua/surface.cpp" 2
# 1 "include/lib/dosadi_libc/math.h" 1
# 1 "include/lib/dosadi_libc/fdlibm.h" 1
# 42 "include/lib/dosadi_libc/fdlibm.h"
extern int signgam;
enum fdversion {fdlibm_ieee = -1, fdlibm_svid, fdlibm_xopen, fdlibm_posix};
# 58 "include/lib/dosadi_libc/fdlibm.h"
extern enum fdversion _fdlib_version;
struct exception {
int type;
char *name;
double arg1;
double arg2;
double retval;
};
# 94 "include/lib/dosadi_libc/fdlibm.h"
extern double acos (double);
extern double asin (double);
extern double atan (double);
extern double atan2 (double, double);
extern double cos (double);
extern double sin (double);
extern double tan (double);
extern double cosh (double);
extern double sinh (double);
extern double tanh (double);
extern double exp (double);
extern double frexp (double, int *);
extern double ldexp (double, int);
extern double log (double);
extern double log10 (double);
extern double modf (double, double *);
extern double pow (double, double);
extern double sqrt (double);
extern double ceil (double);
extern double fabs (double);
extern double floor (double);
extern double fmod (double, double);
extern double erf (double);
extern double erfc (double);
extern double gamma (double);
extern double hypot (double, double);
extern int isnan (double);
extern int finite (double);
extern double j0 (double);
extern double j1 (double);
extern double jn (int, double);
extern double lgamma (double);
extern double y0 (double);
extern double y1 (double);
extern double yn (int, double);
extern double acosh (double);
extern double asinh (double);
extern double atanh (double);
extern double cbrt (double);
extern double logb (double);
extern double nextafter (double, double);
extern double remainder (double, double);
extern double scalb (double, double);
extern int matherr (struct exception *);
extern double significand (double);
extern double copysign (double, double);
extern int ilogb (double);
extern double rint (double);
extern double scalbn (double, int);
extern double expm1 (double);
extern double log1p (double);
# 179 "include/lib/dosadi_libc/fdlibm.h"
extern double __ieee754_sqrt (double);
extern double __ieee754_acos (double);
extern double __ieee754_acosh (double);
extern double __ieee754_log (double);
extern double __ieee754_atanh (double);
extern double __ieee754_asin (double);
extern double __ieee754_atan2 (double,double);
extern double __ieee754_exp (double);
extern double __ieee754_cosh (double);
extern double __ieee754_fmod (double,double);
extern double __ieee754_pow (double,double);
extern double __ieee754_lgamma_r (double,int *);
extern double __ieee754_gamma_r (double,int *);
extern double __ieee754_lgamma (double);
extern double __ieee754_gamma (double);
extern double __ieee754_log10 (double);
extern double __ieee754_sinh (double);
extern double __ieee754_hypot (double,double);
extern double __ieee754_j0 (double);
extern double __ieee754_j1 (double);
extern double __ieee754_y0 (double);
extern double __ieee754_y1 (double);
extern double __ieee754_jn (int,double);
extern double __ieee754_yn (int,double);
extern double __ieee754_remainder (double,double);
extern int __ieee754_rem_pio2 (double,double*);
extern double __ieee754_scalb (double,double);
# 5 "include/lib/dosadi_libc/math.h" 2
# 3 "modules/aqua/surface.cpp" 2
# 17 "modules/aqua/surface.cpp"
inline byte_u CLAMP_BYTE(int x)
{ return (x > 255 ? 255 :
( x < 0 ? 0 : (byte_u)x )); }
static byte_u *blend_table=0;
static void init_blend_table()
{
# 42 "modules/aqua/surface.cpp"
float color;
blend_table = new byte_u[256*256];
for(int i=0; i<256; ++i)
{
color = i;
for(int j=0; j<256; ++j)
{
blend_table[((j)<<8) + (i)] = (byte_u)(color *
(((float)j) / 255.0));
}
}
}
dosadi::Aqua::Surface::Surface():surf(0), width(0), height(0), pen_mode(0),
rub_surf(0)
{
if (blend_table==0)
init_blend_table();
}
dosadi::Aqua::Surface::~Surface()
{
if (surf) delete [] surf;
}
dosadi::Aqua::Surface::Surface(tetra_u w, tetra_u h):width(w), height(h),
pen_mode(0), rub_surf(0)
{
surf = new Pixel[w*h];
clip.Set(0,0,w,h);
}
bool
dosadi::Aqua::Surface::Create(tetra_u w, tetra_u h)
{
if (surf) return false;
width=w;
height=h;
surf = new Pixel[w*h];
clip.Set(0,0,w-1,h-1);
if (surf==0)
return false;
else
return true;
}
void
dosadi::Aqua::Surface::Select(Surface *rub)
{
rub_surf = rub;
}
void
dosadi::Aqua::Surface::setClip(const geom::gRect &r)
{
clip.Set(r);
if (clip.xmin < 0) clip.xmin=0;
if (clip.ymin < 0) clip.ymin=0;
if (clip.xmax > width-1) clip.xmax=width-1;
if (clip.ymax > height-1) clip.ymax=height-1;
}
void
dosadi::Aqua::Surface::Clear(Pixel c)
{
__asm__ __volatile__("cld\n"
"movl %0, %%edi\n"
"movl %1, %%eax\n"
"movl %2, %%ecx\n"
"repnz stosl\n"
:
: "rm" (surf), "rm"
(c.t), "rm" ((width*height)>>2)
: "eax", "edi", "ecx", "flags"
);
}
bool
dosadi::Aqua::Surface::getPixel(float x, float y, Pixel &c)
{
if (surf==0 || !clip.Contains(x,y))
return false;
c = surf[(int)(((y)*width)+(x))];
return true;
}
bool
dosadi::Aqua::Surface::getMappedPixel(float x, float y, float w, float h,
Pixel &c)
{
if (surf==0)
return false;
float u = (x*width) / w,
v = (y*height) / h;
if (!clip.Contains(u,v))
return false;
c = surf[(int)(((v)*width)+(u))];
return true;
}
bool
dosadi::Aqua::Surface::getTiledPixel(float x, float y, Pixel &c)
{
if (surf==0)
return false;
float tx, ty;
asm("fild %3\n"
"fld %2\n"
"fprem1\n"
"fstp %1\n"
"fild %5\n"
"fld %4\n"
"fprem1\n"
"fstp %0\n"
: "=rm" (tx), "=rm" (ty)
: "rm" (y), "rm" (height), "rm" (x), "rm" (width)
: "st", "st(1)"
);
if (!clip.Contains(tx,ty))
return false;
c = surf[(int)(((ty)*width)+(tx))];
return true;
}
bool
dosadi::Aqua::Surface::putPixel(float x, float y, const Pixel &c)
{
Pixel t;
byte_u src_alpha, dst_alpha;
if (surf==0 || !clip.Contains(x,y))
return false;
switch(pen_mode)
{
case PEN_COPY:
surf[(int)(((y)*width)+(x))].t = c.t;
break;
case PEN_ALPHA_AVG:
t.t = surf[(int)(((y)*width)+(x))].t;
dst_alpha = (c.b.a+t.b.a)>>1;
src_alpha = 255-dst_alpha;
t.b.b = blend_table[((src_alpha)<<8) + (t.b.b)] +
blend_table[((dst_alpha)<<8) + (c.b.b)];
t.b.g = blend_table[((src_alpha)<<8) + (t.b.g)] +
blend_table[((dst_alpha)<<8) + (c.b.g)];
t.b.r = blend_table[((src_alpha)<<8) + (t.b.r)] +
blend_table[((dst_alpha)<<8) + (c.b.r)];
surf[(int)(((y)*width)+(x))].t = t.t;
break;
case PEN_ALPHA_SRC:
t.t = surf[(int)(((y)*width)+(x))].t;
dst_alpha = t.b.a;
src_alpha = 255-dst_alpha;
t.b.b = blend_table[((src_alpha)<<8) + (t.b.b)] +
blend_table[((dst_alpha)<<8) + (c.b.b)];
t.b.g = blend_table[((src_alpha)<<8) + (t.b.g)] +
blend_table[((dst_alpha)<<8) + (c.b.g)];
t.b.r = blend_table[((src_alpha)<<8) + (t.b.r)] +
blend_table[((dst_alpha)<<8) + (c.b.r)];
surf[(int)(((y)*width)+(x))].t = t.t;
break;
case PEN_ALPHA_DST:
t.t = surf[(int)(((y)*width)+(x))].t;
dst_alpha = c.b.a;
src_alpha = 255-dst_alpha;
t.b.b = blend_table[((src_alpha)<<8) + (t.b.b)] +
blend_table[((dst_alpha)<<8) + (c.b.b)];
t.b.g = blend_table[((src_alpha)<<8) + (t.b.g)] +
blend_table[((dst_alpha)<<8) + (c.b.g)];
t.b.r = blend_table[((src_alpha)<<8) + (t.b.r)] +
blend_table[((dst_alpha)<<8) + (c.b.r)];
surf[(int)(((y)*width)+(x))].t = t.t;
break;
case PEN_XOR:
surf[(int)(((y)*width)+(x))].t ^= c.t;
break;
case PEN_AND:
surf[(int)(((y)*width)+(x))].t &= c.t;
break;
case PEN_OR:
surf[(int)(((y)*width)+(x))].t |= c.t;
break;
case PEN_ADD:
t.t = surf[(int)(((y)*width)+(x))].t;
t.b.r = CLAMP_BYTE(t.b.r + c.b.r);
t.b.g = CLAMP_BYTE(t.b.g + c.b.g);
t.b.b = CLAMP_BYTE(t.b.b + c.b.b);
surf[(int)(((y)*width)+(x))].t = t.t;
break;
case PEN_SUB:
t.t = surf[(int)(((y)*width)+(x))].t;
t.b.r = CLAMP_BYTE(t.b.r - c.b.r);
t.b.g = CLAMP_BYTE(t.b.g - c.b.g);
t.b.b = CLAMP_BYTE(t.b.b - c.b.b);
surf[(int)(((y)*width)+(x))].t = t.t;
break;
case PEN_RUB:
{
Pixel rc;
if (rub_surf && rub_surf->getPixel(x,y,rc))
{
if (rc.t!=c.t)
surf[(int)(((y)*width)+(x))].t = rc.t;
}
else return false;
}
break;
case PEN_RUB_MAP:
{
Pixel rc;
if (rub_surf && rub_surf->getMappedPixel
(x,y,width,height,rc))
{
if (rc.t!=c.t)
surf[(int)(((y)*width)+(x))].t = rc.t;
}
else return false;
}
break;
default:
return false;
};
return true;
}
void
dosadi::Aqua::Surface::drawHLine(float x, float y, float w, const Pixel &c)
{
for(float i=x; i<x+w; ++i)
putPixel(i,y,c);
}
void
dosadi::Aqua::Surface::drawVLine(float x, float y, float h, const Pixel &c)
{
for(float i=y; i<y+h; ++i)
putPixel(x,i,c);
}
void
dosadi::Aqua::Surface::drawLine(const geom::gRect &r, const Pixel &c)
{
float x1=r.xmin,
x2=r.xmax,
y1=r.ymin,
y2=r.ymax,
x, y, dx, dy, sx, sy, m;
dx = x2-x1;
dy = y2-y1;
sx = (((dx)<0) ? -1 : (dx)>0 ? 1 : 0);
sy = (((dy)<0) ? -1 : (dy)>0 ? 1 : 0);
if (dx > dy)
{
m = dy/dx;
y = y1;
for(x=x1; x<=x2; x+=sx)
{
putPixel(x, y, c);
y+=m;
}
}
else
{
m = dx/dy;
x = x1;
for(y=y1; y<=y2; y+=sy)
{
putPixel(x, y, c);
x+=m;
}
}
}
void
dosadi::Aqua::Surface::drawRect(const geom::gRect &r, const Pixel &c)
{
drawHLine(r.xmin, r.ymin, r.Width(), c);
drawHLine(r.xmin, r.ymax, r.Width(), c);
drawVLine(r.xmin, r.ymin, r.Height(), c);
drawVLine(r.xmax, r.ymin, r.Height(), c);
}
void
dosadi::Aqua::Surface::fillRect(const geom::gRect &r, const Pixel &c)
{
float w = r.Width();
for(float y=r.ymin; y<=r.ymax; ++y)
drawHLine(r.xmin, y, w, c);
}
# 410 "modules/aqua/surface.cpp"
void
dosadi::Aqua::Surface::drawCircle(const geom::gRect &r, const Pixel &c)
{
float radius = (r.Width() + r.Height()) / 4.0,
cx = r.xmin+radius,
cy = r.ymin+radius,
x = radius,
y = 0,
x_change = 1 - 2 * radius,
y_change = 1,
radius_error = 0;
while(x>=y)
{
putPixel(cx+x, cy+y, c); putPixel(cx-x, cy+y, c); putPixel(cx-
x, cy-y, c); putPixel(cx+x, cy-y, c); putPixel(cx+y, cy+x, c); putPixel(cx-y,
cy+x, c); putPixel(cx-y, cy-x, c); putPixel(cx+y, cy-x, c);;
++y;
radius_error+=y_change;
y_change+=2;
if (2*radius_error + x_change > 0)
{
--x;
radius_error+=x_change;
x_change+=2;
}
}
}
void
dosadi::Aqua::Surface::fillCircle(const geom::gRect &r, const Pixel &c)
{
float radius = (r.Width() + r.Height()) / 4.0,
cx = r.xmin+radius,
cy = r.ymin+radius,
x = radius,
y = 0,
x_change = 1 - 2 * radius,
y_change = 1,
radius_error = 0;
while(x>=y)
{
{ float x2 = x*2, y2 = y*2; drawHLine(cx-x, cy+y, x2, c);
drawHLine(cx-y, cy+x, y2, c); drawHLine(cx-x, cy-y, x2, c); drawHLine(cx-y, cy-
x, y2, c); };
++y;
radius_error+=y_change;
y_change+=2;
if (2*radius_error + x_change > 0)
{
--x;
radius_error+=x_change;
x_change+=2;
}
}
}
# 478 "modules/aqua/surface.cpp"
void
dosadi::Aqua::Surface::drawEllipse(const geom::gRect &r, const Pixel &c)
{
float rx = r.Width() / 2.0,
ry = r.Height() / 2.0,
cx = r.xmin+rx,
cy = r.ymin+ry,
x = rx,
y = 0,
x_change = ry*ry*(1-2*rx),
y_change = rx*rx,
two_a_square = 2*rx*rx,
two_b_square = 2*ry*ry,
stopping_x = two_b_square * rx,
stopping_y = 0,
ellipse_error = 0;
while(stopping_x >= stopping_y)
{
putPixel(cx+x, cy+y, c); putPixel(cx-x, cy+y, c); putPixel(cx-
x, cy-y, c); putPixel(cx+x, cy-y, c);;
++y;
stopping_y+=two_a_square;
ellipse_error+=y_change;
y_change+=two_a_square;
if ((2 * ellipse_error + x_change) > 0)
{
--x;
stopping_x-=two_b_square;
ellipse_error+=x_change;
x_change+=two_b_square;
}
}
x=0;
y=ry;
x_change = ry*ry;
y_change = rx*rx*(1-2*ry);
ellipse_error = 0;
stopping_x = 0;
stopping_y = two_a_square * ry;
while(stopping_x <= stopping_y)
{
putPixel(cx+x, cy+y, c); putPixel(cx-x, cy+y, c); putPixel(cx-
x, cy-y, c); putPixel(cx+x, cy-y, c);;
++x;
stopping_x+=two_b_square;
ellipse_error+=x_change;
x_change+=two_b_square;
if((2 * ellipse_error + y_change) > 0)
{
--y;
stopping_y-=two_a_square;
ellipse_error+=y_change;
y_change+=two_a_square;
}
}
}
void
dosadi::Aqua::Surface::fillEllipse(const geom::gRect &r, const Pixel &c)
{
float rx = r.Width() / 2.0,
ry = r.Height() / 2.0,
cx = r.xmin+rx,
cy = r.ymin+ry,
x = rx,
y = 0,
x_change = ry*ry*(1-2*rx),
y_change = rx*rx,
two_a_square = 2*rx*rx,
two_b_square = 2*ry*ry,
stopping_x = two_b_square * rx,
stopping_y = 0,
ellipse_error = 0;
while(stopping_x >= stopping_y)
{
{ float x2 = x*2; drawHLine(cx-x, cy+y, x2, c); drawHLine(cx-
x, cy-y, x2, c); };
++y;
stopping_y+=two_a_square;
ellipse_error+=y_change;
y_change+=two_a_square;
if ((2 * ellipse_error + x_change) > 0)
{
--x;
stopping_x-=two_b_square;
ellipse_error+=x_change;
x_change+=two_b_square;
}
}
x=0;
y=ry;
x_change = ry*ry;
y_change = rx*rx*(1-2*ry);
ellipse_error = 0;
stopping_x = 0;
stopping_y = two_a_square * ry;
while(stopping_x <= stopping_y)
{
{ float x2 = x*2; drawHLine(cx-x, cy+y, x2, c); drawHLine(cx-
x, cy-y, x2, c); };
++x;
stopping_x+=two_b_square;
ellipse_error+=x_change;
x_change+=two_b_square;
if((2 * ellipse_error + y_change) > 0)
{
--y;
stopping_y-=two_a_square;
ellipse_error+=y_change;
y_change+=two_a_square;
}
}
}
void
dosadi::Aqua::Surface::drawQuarterCircle(const geom::gRect &r, byte_u
quadrant, const Pixel &c)
{
float radius = (r.Width() + r.Height()) / 4.0,
cx = r.xmin+radius,
cy = r.ymin+radius,
x = radius,
y = 0,
x_change = 1 - 2 * radius,
y_change = 1,
radius_error = 0;
while(x>=y)
{
switch(quadrant)
{
case CURVE_QUAD_UL:
putPixel(cx-x, cy+y, c);
putPixel(cx-y, cy+x, c);
break;
case CURVE_QUAD_LL:
putPixel(cx-x, cy-y, c);
putPixel(cx-y, cy-x, c);
break;
case CURVE_QUAD_UR:
putPixel(cx+x, cy+y, c);
putPixel(cx+y, cy+x, c);
break;
case CURVE_QUAD_LR:
putPixel(cx+x, cy-y, c);
putPixel(cx+y, cy-x, c);
break;
}
++y;
radius_error+=y_change;
y_change+=2;
if (2*radius_error + x_change > 0)
{
--x;
radius_error+=x_change;
x_change+=2;
}
}
}
void
dosadi::Aqua::Surface::fillQuarterCircle(const geom::gRect &r, byte_u
quadrant, const Pixel &c)
{
float radius = (r.Width() + r.Height()) / 4.0,
cx = r.xmin+radius,
cy = r.ymin+radius,
x = radius,
y = 0,
x_change = 1 - 2 * radius,
y_change = 1,
radius_error = 0;
while(x>=y)
{
switch(quadrant)
{
case CURVE_QUAD_UL:
drawHLine(cx-x, cy+y, x, c);
drawHLine(cx-y, cy+x, y, c);
break;
case CURVE_QUAD_LL:
drawHLine(cx-x, cy-y, x, c);
drawHLine(cx-y, cy-x, y, c);
break;
case CURVE_QUAD_UR:
drawHLine(cx, cy+y, x, c);
drawHLine(cx, cy+x, y, c);
break;
case CURVE_QUAD_LR:
drawHLine(cx, cy-y, x, c);
drawHLine(cx, cy-x, y, c);
break;
}
++y;
radius_error+=y_change;
y_change+=2;
if (2*radius_error + x_change > 0)
{
--x;
radius_error+=x_change;
x_change+=2;
}
}
}
void
dosadi::Aqua::Surface::drawQuarterEllipse(const geom::gRect &r, byte_u
quadrant, const Pixel &c)
{
float rx = r.Width() / 2.0,
ry = r.Height() / 2.0,
cx = r.xmin+rx,
cy = r.ymin+ry,
x = rx,
y = 0,
x_change = ry*ry*(1-2*rx),
y_change = rx*rx,
two_a_square = 2*rx*rx,
two_b_square = 2*ry*ry,
stopping_x = two_b_square * rx,
stopping_y = 0,
ellipse_error = 0;
while(stopping_x >= stopping_y)
{
switch(quadrant)
{
case CURVE_QUAD_UL:
putPixel(cx-x, cy+y, c);
break;
case CURVE_QUAD_LL:
putPixel(cx-x, cy-y, c);
break;
case CURVE_QUAD_UR:
putPixel(cx+x, cy+y, c);
break;
case CURVE_QUAD_LR:
putPixel(cx+x, cy-y, c);
break;
}
++y;
stopping_y+=two_a_square;
ellipse_error+=y_change;
y_change+=two_a_square;
if ((2 * ellipse_error + x_change) > 0)
{
--x;
stopping_x-=two_b_square;
ellipse_error+=x_change;
x_change+=two_b_square;
}
}
x=0;
y=ry;
x_change = ry*ry;
y_change = rx*rx*(1-2*ry);
ellipse_error = 0;
stopping_x = 0;
stopping_y = two_a_square * ry;
while(stopping_x <= stopping_y)
{
switch(quadrant)
{
case CURVE_QUAD_UL:
putPixel(cx-x, cy+y, c);
break;
case CURVE_QUAD_LL:
putPixel(cx-x, cy-y, c);
break;
case CURVE_QUAD_UR:
putPixel(cx+x, cy+y, c);
break;
case CURVE_QUAD_LR:
putPixel(cx+x, cy-y, c);
break;
}
++x;
stopping_x+=two_b_square;
ellipse_error+=x_change;
x_change+=two_b_square;
if((2 * ellipse_error + y_change) > 0)
{
--y;
stopping_y-=two_a_square;
ellipse_error+=y_change;
y_change+=two_a_square;
}
}
}
void
dosadi::Aqua::Surface::fillQuarterEllipse(const geom::gRect &r, byte_u
quadrant, const Pixel &c)
{
float rx = r.Width() / 2.0,
ry = r.Height() / 2.0,
cx = r.xmin+rx,
cy = r.ymin+ry,
x = rx,
y = 0,
x_change = ry*ry*(1-2*rx),
y_change = rx*rx,
two_a_square = 2*rx*rx,
two_b_square = 2*ry*ry,
stopping_x = two_b_square * rx,
stopping_y = 0,
ellipse_error = 0;
while(stopping_x >= stopping_y)
{
switch(quadrant)
{
case CURVE_QUAD_UL:
drawHLine(cx-x, cy+y, x, c);
break;
case CURVE_QUAD_LL:
drawHLine(cx-x, cy-y, x, c);
break;
case CURVE_QUAD_UR:
drawHLine(cx, cy+y, x, c);
break;
case CURVE_QUAD_LR:
drawHLine(cx, cy-y, x, c);
break;
}
++y;
stopping_y+=two_a_square;
ellipse_error+=y_change;
y_change+=two_a_square;
if ((2 * ellipse_error + x_change) > 0)
{
--x;
stopping_x-=two_b_square;
ellipse_error+=x_change;
x_change+=two_b_square;
}
}
x=0;
y=ry;
x_change = ry*ry;
y_change = rx*rx*(1-2*ry);
ellipse_error = 0;
stopping_x = 0;
stopping_y = two_a_square * ry;
while(stopping_x <= stopping_y)
{
switch(quadrant)
{
case CURVE_QUAD_UL:
drawHLine(cx-x, cy+y, x, c);
break;
case CURVE_QUAD_LL:
drawHLine(cx-x, cy-y, x, c);
break;
case CURVE_QUAD_UR:
drawHLine(cx, cy+y, x, c);
break;
case CURVE_QUAD_LR:
drawHLine(cx, cy-y, x, c);
break;
}
++x;
stopping_x+=two_b_square;
ellipse_error+=x_change;
x_change+=two_b_square;
if((2 * ellipse_error + y_change) > 0)
{
--y;
stopping_y-=two_a_square;
ellipse_error+=y_change;
y_change+=two_a_square;
}
}
}
void
dosadi::Aqua::Surface::blitSurface(Surface &s, const geom::gRect &src, const
geom::gRect &dst)
{
geom::gRect src_r(src),
dst_r(dst);
src_r.intersect(s.getClip());
dst_r.intersect(getClip());
src_r.Minimum(dst_r);
tetra_u src_x = (tetra_u)src_r.xmin,
dst_x = (tetra_u)dst_r.xmin,
src_y = (tetra_u)src_r.ymin,
dst_y = (tetra_u)dst_r.ymin,
line_w = (tetra_u)src_r.Width(),
rect_h = (tetra_u)src_r.Height(),
src_w = s.Width(),
dst_w = Width();
tetra_u src_ofs = src_x + (src_y * src_w),
dst_ofs = dst_x + (dst_y * dst_w);
for(tetra_u i = 0; i<rect_h; ++i)
{
asm volatile ("cld\n"
"movl %0, %%edi\n"
"movl %1, %%esi\n"
"movl %2, %%ecx\n"
"repnz movsl\n"
:
: "rm" (surf), "rm"
(s.surf), "rm" (line_w)
: "esi", "edi", "ecx",
"flags");
src_ofs += src_w;
dst_ofs += dst_w;
}
}
void
dosadi::Aqua::Surface::blitMaskedSurface(Surface &s, const geom::gRect &src,
const geom::gRect &dst, const Pixel &c)
{
geom::gRect src_r(src),
dst_r(dst);
src_r.intersect(s.getClip());
dst_r.intersect(getClip());
src_r.Minimum(dst_r);
tetra_u src_x = (tetra_u)src_r.xmin,
dst_x = (tetra_u)dst_r.xmin,
src_y = (tetra_u)src_r.ymin,
dst_y = (tetra_u)dst_r.ymin,
line_w = (tetra_u)src_r.Width(),
rect_h = (tetra_u)src_r.Height(),
src_w = s.Width(),
dst_w = Width();
tetra_u src_ofs = src_x + (src_y * src_w),
dst_ofs = dst_x + (dst_y * dst_w);
for(tetra_u i = 0; i<rect_h; ++i)
{
asm volatile ("cld\n"
"movl %2, %%ecx\n"
"blit_move_repeat:\n"
"lodsl\n"
"cmp %%eax, %3\n"
"loope
blit_move_repeat\n"
"jcxz
blit_move_done\n"
"stosl\n"
"loop
blit_move_repeat\n"
"blit_move_done:\n"
:
: "edi" (surf), "esi"
(s.surf), "rm" (line_w), "rm" (c.t)
: "eax", "ecx", "flags
");
src_ofs += src_w;
dst_ofs += dst_w;
}
}