mirror of
https://gitea.nishi.boats/pyrite-dev/milsko
synced 2026-01-06 01:19:44 +00:00
closes #10
git-svn-id: http://svn2.nishi.boats/svn/milsko/trunk@570 b9cfdab3-6d41-4d17-bbe4-086880011989
This commit is contained in:
@@ -2,13 +2,33 @@
|
|||||||
|
|
||||||
#include <Mw/Milsko.h>
|
#include <Mw/Milsko.h>
|
||||||
|
|
||||||
int main() {
|
MwWidget cpicker;
|
||||||
MwWidget w = MwVaCreateWidget(MwWindowClass, "main", NULL, MwDEFAULT,
|
MwWidget window;
|
||||||
MwDEFAULT, 640, 480, MwNtitle, "test", NULL);
|
MwWidget button;
|
||||||
|
|
||||||
MwWidget cpicker = MwColorPicker(w, "cpicker");
|
void color_callback(MwRGB rgb) {
|
||||||
|
char hexColor[8];
|
||||||
|
|
||||||
(void)cpicker;
|
sprintf(hexColor, "#%02X%02X%02X", rgb.r, rgb.g, rgb.b);
|
||||||
|
MwSetText(window, MwNbackground, hexColor);
|
||||||
MwLoop(w);
|
}
|
||||||
|
|
||||||
|
void color_picker(MwWidget handle, void* user_data, void* call_data) {
|
||||||
|
MwWidget cpicker = MwColorPicker(window, "cpicker", color_callback);
|
||||||
|
MwSetText(cpicker, MwNbackground, MwDefaultBackground);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
window = MwVaCreateWidget(MwWindowClass, "main", NULL, MwDEFAULT,
|
||||||
|
MwDEFAULT, 640, 480, MwNtitle, "color picker", NULL);
|
||||||
|
MwSetText(window, MwNbackground, "#000000");
|
||||||
|
|
||||||
|
button = MwVaCreateWidget(MwButtonClass, "button", window, 160, 180, 320, 120,
|
||||||
|
MwNtext, "change window background",
|
||||||
|
NULL);
|
||||||
|
MwSetText(button, MwNbackground, MwDefaultBackground);
|
||||||
|
|
||||||
|
MwAddUserHandler(button, MwNactivateHandler, color_picker, NULL);
|
||||||
|
|
||||||
|
MwLoop(window);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,21 +15,16 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct _MwRGB MwRGB;
|
typedef struct _MwRGB MwRGB;
|
||||||
typedef struct _MwHSV MwHSV;
|
|
||||||
|
|
||||||
struct _MwRGB {
|
struct _MwRGB {
|
||||||
double r;
|
MwU32 r;
|
||||||
double g;
|
MwU32 g;
|
||||||
double b;
|
MwU32 b;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MwHSV {
|
typedef void (*MwColorPickerCallback)(MwRGB rgb);
|
||||||
double h; // angle in degrees
|
|
||||||
double s; // a fraction between 0 and 1
|
|
||||||
double v; // a fraction between 0 and 1
|
|
||||||
};
|
|
||||||
|
|
||||||
MWDECL MwWidget MwColorPicker(MwWidget handle, const char* title);
|
MWDECL MwWidget MwColorPicker(MwWidget handle, const char* title, MwColorPickerCallback cb);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,6 +143,16 @@ MWDECL void MwGetColor(MwLLColor color, int* red, int* green, int* blue);
|
|||||||
*/
|
*/
|
||||||
MWDECL MwLLPixmap MwLoadRaw(MwWidget handle, unsigned char* rgb, int width, int height);
|
MWDECL MwLLPixmap MwLoadRaw(MwWidget handle, unsigned char* rgb, int width, int height);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Creates a pixmap from raw data
|
||||||
|
* @param handle Widget
|
||||||
|
* @param rgb RGBA data
|
||||||
|
* @param width Width
|
||||||
|
* @param height Height
|
||||||
|
* @return Pixmap
|
||||||
|
*/
|
||||||
|
MWDECL void MwReloadRaw(MwWidget handle, unsigned char* rgb, int width, int height, MwLLPixmap pixmap);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Creates a pixmap from XPM data
|
* @brief Creates a pixmap from XPM data
|
||||||
* @param handle Widget
|
* @param handle Widget
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ MWDECL void MwLLPolygon(MwLL handle, MwPoint* points, int points_count, MwLLColo
|
|||||||
MWDECL void MwLLLine(MwLL handle, MwPoint* points, MwLLColor color);
|
MWDECL void MwLLLine(MwLL handle, MwPoint* points, MwLLColor color);
|
||||||
|
|
||||||
MWDECL MwLLColor MwLLAllocColor(MwLL handle, int r, int g, int b);
|
MWDECL MwLLColor MwLLAllocColor(MwLL handle, int r, int g, int b);
|
||||||
|
MWDECL void MwLLColorUpdate(MwLL handle, int r, int g, int b, MwLLColor c);
|
||||||
MWDECL void MwLLFreeColor(MwLLColor color);
|
MWDECL void MwLLFreeColor(MwLLColor color);
|
||||||
|
|
||||||
MWDECL void MwLLGetXYWH(MwLL handle, int* x, int* y, unsigned int* w, unsigned int* h);
|
MWDECL void MwLLGetXYWH(MwLL handle, int* x, int* y, unsigned int* w, unsigned int* h);
|
||||||
@@ -105,6 +106,7 @@ MWDECL void MwLLNextEvent(MwLL handle);
|
|||||||
MWDECL void MwLLSleep(int ms);
|
MWDECL void MwLLSleep(int ms);
|
||||||
|
|
||||||
MWDECL MwLLPixmap MwLLCreatePixmap(MwLL handle, unsigned char* data, int width, int height);
|
MWDECL MwLLPixmap MwLLCreatePixmap(MwLL handle, unsigned char* data, int width, int height);
|
||||||
|
MWDECL void MwLLPixmapUpdate(MwLL handle, MwLLPixmap pixmap);
|
||||||
MWDECL void MwLLDestroyPixmap(MwLLPixmap pixmap);
|
MWDECL void MwLLDestroyPixmap(MwLLPixmap pixmap);
|
||||||
MWDECL void MwLLDrawPixmap(MwLL handle, MwRect* rect, MwLLPixmap pixmap);
|
MWDECL void MwLLDrawPixmap(MwLL handle, MwRect* rect, MwLLPixmap pixmap);
|
||||||
MWDECL void MwLLSetIcon(MwLL handle, MwLLPixmap pixmap);
|
MWDECL void MwLLSetIcon(MwLL handle, MwLLPixmap pixmap);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
/*!
|
/*!
|
||||||
* @file Mw/LowLevelMath.h
|
* @file Mw/LowLevelMath.h
|
||||||
* @brief A few portable functions for supporting simultaneously supporting SIMD and not supporting it
|
* @brief A few portable functions for simultaneously supporting SIMD and not supporting it
|
||||||
* @warning This is mostly used internally. Anything undocumented, and/or anything with an _ prefix (that doesn't have a corresponding typedef) should be avoided.
|
* @warning This is mostly used internally. Anything undocumented, and/or anything with an _ prefix (that doesn't have a corresponding typedef) should be avoided.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -12,70 +12,123 @@
|
|||||||
#include <Mw/MachDep.h>
|
#include <Mw/MachDep.h>
|
||||||
|
|
||||||
#if defined(__i386__) || defined(__x86_64__) || defined(__WATCOMC__)
|
#if defined(__i386__) || defined(__x86_64__) || defined(__WATCOMC__)
|
||||||
#define MwLLMathMMX
|
#define MwLLMath_x86
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(MwLLMathMMX)
|
|
||||||
// #warning LowLevelMath.h does not yet support this platform
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Generic vector type
|
* @brief SIMD vector
|
||||||
* @warning Do not try to instantiate this yourself, use the appropriate functions instead.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct _MwLLVec MwLLVec;
|
typedef struct _MwLLVec MwLLVec;
|
||||||
|
|
||||||
typedef union _MwLLVecUnion MwLLVecUnion;
|
/*!
|
||||||
|
* @brief SIMD vector type
|
||||||
|
* @warning Not exhaustive, enums subject to be added later.
|
||||||
|
*/
|
||||||
|
enum MwLLVecType {
|
||||||
|
MwLLVecTypeU8 = 0,
|
||||||
|
MwLLVecTypeU16,
|
||||||
|
MwLLVecTypeU32,
|
||||||
|
MwLLVecTypeU64,
|
||||||
|
MwLLVecTypeI8,
|
||||||
|
MwLLVecTypeI16,
|
||||||
|
MwLLVecTypeI32,
|
||||||
|
MwLLVecTypeI64,
|
||||||
|
|
||||||
// clang-format off
|
MwLLVecType_Max,
|
||||||
struct _MwLLVecDataU8x8 { MwU8 a; MwU8 b; MwU8 c; MwU8 d; MwU8 e; MwU8 f; MwU8 g; MwU8 h;};
|
|
||||||
struct _MwLLVecDataU16x4 { MwU16 a; MwU16 b; MwU16 c; MwU16 d;};
|
|
||||||
struct _MwLLVecDataU32x2 { MwU32 a; MwU32 b;};
|
|
||||||
struct _MwLLVecDataI8x8 { MwI8 a; MwI8 b; MwI8 c; MwI8 d; MwI8 e; MwI8 f; MwI8 g; MwI8 h;};
|
|
||||||
struct _MwLLVecDataI16x4 { MwI16 a; MwI16 b; MwI16 c; MwI16 d;};
|
|
||||||
struct _MwLLVecDataI32x2 { MwI32 a; MwI32 b;};
|
|
||||||
union _MwLLVecUnion {
|
|
||||||
struct _MwLLVecDataU8x8 u8; struct _MwLLVecDataU16x4 u16; struct _MwLLVecDataU32x2 u32;
|
|
||||||
struct _MwLLVecDataI8x8 i8; struct _MwLLVecDataI16x4 i16; struct _MwLLVecDataI32x2 i32;
|
|
||||||
MwU64 all;
|
|
||||||
};
|
|
||||||
// clang-format on
|
|
||||||
enum _MwLLVecType {
|
|
||||||
_MwLLVecTypeU8x8 = 0,
|
|
||||||
_MwLLVecTypeU16x4 = 1,
|
|
||||||
_MwLLVecTypeU32x2 = 2,
|
|
||||||
_MwLLVecTypeI8x8 = 3,
|
|
||||||
_MwLLVecTypeI16x4 = 4,
|
|
||||||
_MwLLVecTypeI32x2 = 5,
|
|
||||||
|
|
||||||
_MwLLVecType_Max,
|
|
||||||
};
|
|
||||||
struct _MwLLVec {
|
|
||||||
int ty;
|
|
||||||
MwLLVecUnion un;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
MWDECL MwLLVec _MwLLVecCreateGeneric(int ty, ...);
|
/*!
|
||||||
|
* @brief Create a SIMD Vector (variadic)
|
||||||
|
* @warning Prefer using the macro version.
|
||||||
|
*/
|
||||||
|
MWDECL MwLLVec* MwLLVaVecCreate(int ty, MwU64 size, ...);
|
||||||
|
|
||||||
#define MwLLVecU8x8(a, b, c, d, e, f, g, h) _MwLLVecCreateGeneric(_MwLLVecTypeU8x8, a, b, c, d, e, f, g, h)
|
/*!
|
||||||
#define MwLLVecU16x4(a, b, c, d) _MwLLVecCreateGeneric(_MwLLVecTypeU16x4, a, b, c, d)
|
* @brief Destroy the given SIMD Vector
|
||||||
#define MwLLVecU32x2(a, b) _MwLLVecCreateGeneric(_MwLLVecTypeU32x2, a, b)
|
*/
|
||||||
#define MwLLVecI8x8(a, b, c, d, e, f, g, h) _MwLLVecCreateGeneric(_MwLLVecTypeI8x8, a, b, c, d, e, f, g, h)
|
MWDECL void MwLLVecDestroy(MwLLVec* vec);
|
||||||
#define MwLLVecI16x4(a, b, c, d) _MwLLVecCreateGeneric(_MwLLVecTypeI16x4, a, b, c, d)
|
|
||||||
#define MwLLVecI32x2(a, b) _MwLLVecCreateGeneric(_MwLLVecTypeI32x2, a, b)
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief index the given SIMD Vector (u8)
|
||||||
|
*/
|
||||||
|
MWDECL MwU8 MwLLVecIndexU8(MwLLVec* vec, MwU64 index);
|
||||||
|
/*!
|
||||||
|
* @brief index the given SIMD Vector (u16)
|
||||||
|
*/
|
||||||
|
MWDECL MwU16 MwLLVecIndexU16(MwLLVec* vec, MwU64 index);
|
||||||
|
/*!
|
||||||
|
* @brief index the given SIMD Vector (u32)
|
||||||
|
*/
|
||||||
|
MWDECL MwU32 MwLLVecIndexU32(MwLLVec* vec, MwU64 index);
|
||||||
|
/*!
|
||||||
|
* @brief index the given SIMD Vector (u64)
|
||||||
|
*/
|
||||||
|
MWDECL MwU64 MwLLVecIndexU64(MwLLVec* vec, MwU64 index);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief index the given SIMD Vector (i8)
|
||||||
|
*/
|
||||||
|
MWDECL MwI8 MwLLVecIndexI8(MwLLVec* vec, MwU64 index);
|
||||||
|
/*!
|
||||||
|
* @brief index the given SIMD Vector (i16)
|
||||||
|
*/
|
||||||
|
MWDECL MwI16 MwLLVecIndexI16(MwLLVec* vec, MwU64 index);
|
||||||
|
/*!
|
||||||
|
* @brief index the given SIMD Vector (i32)
|
||||||
|
*/
|
||||||
|
MWDECL MwI32 MwLLVecIndexI32(MwLLVec* vec, MwU64 index);
|
||||||
|
/*!
|
||||||
|
* @brief index the given SIMD Vector (i64)
|
||||||
|
*/
|
||||||
|
MWDECL MwI64 MwLLVecIndexI64(MwLLVec* vec, MwU64 index);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief SIMD Vector add
|
||||||
|
*/
|
||||||
MWDECL void MwLLMathAdd(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
MWDECL void MwLLMathAdd(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||||
|
/*!
|
||||||
|
* @brief SIMD Vector multiply
|
||||||
|
*/
|
||||||
MWDECL void MwLLMathMultiply(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
MWDECL void MwLLMathMultiply(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||||
|
/*!
|
||||||
|
* @brief SIMD Vector subtract
|
||||||
|
*/
|
||||||
MWDECL void MwLLMathSub(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
MWDECL void MwLLMathSub(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||||
|
/*!
|
||||||
|
* @brief SIMD Vector reciprocal
|
||||||
|
*/
|
||||||
MWDECL void MwLLMathReciprocal(MwLLVec* a, MwLLVec* out);
|
MWDECL void MwLLMathReciprocal(MwLLVec* a, MwLLVec* out);
|
||||||
|
/*!
|
||||||
|
* @brief SIMD Vector square root
|
||||||
|
*/
|
||||||
MWDECL void MwLLMathSquareRoot(MwLLVec* a, MwLLVec* out);
|
MWDECL void MwLLMathSquareRoot(MwLLVec* a, MwLLVec* out);
|
||||||
|
/*!
|
||||||
|
* @brief SIMD Vector bitwise and
|
||||||
|
*/
|
||||||
MWDECL void MwLLMathAnd(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
MWDECL void MwLLMathAnd(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||||
|
/*!
|
||||||
|
* @brief SIMD Vector bitwise or
|
||||||
|
*/
|
||||||
MWDECL void MwLLMathOr(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
MWDECL void MwLLMathOr(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||||
|
/*!
|
||||||
|
* @brief SIMD Vector bitwise shift right
|
||||||
|
*/
|
||||||
MWDECL void MwLLMathShiftRight(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
MWDECL void MwLLMathShiftRight(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||||
|
/*!
|
||||||
|
* @brief SIMD Vector bitwise shift left
|
||||||
|
*/
|
||||||
MWDECL void MwLLMathShiftLeft(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
MWDECL void MwLLMathShiftLeft(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||||
|
/*!
|
||||||
|
* @brief SIMD Vector bitwise equal
|
||||||
|
*/
|
||||||
MWDECL void MwLLMathEqual(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
MWDECL void MwLLMathEqual(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||||
|
/*!
|
||||||
|
* @brief SIMD Vector greater then
|
||||||
|
*/
|
||||||
MWDECL void MwLLMathGreaterThen(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
MWDECL void MwLLMathGreaterThen(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||||
|
/*!
|
||||||
|
* @brief SIMD Vector lesser then
|
||||||
|
*/
|
||||||
MWDECL void MwLLMathLesserThen(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
MWDECL void MwLLMathLesserThen(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -43,8 +43,9 @@ struct _MwLLColor {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct _MwLLPixmap {
|
struct _MwLLPixmap {
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
|
unsigned char* data_scratch_buf;
|
||||||
|
|
||||||
HBITMAP hBitmap;
|
HBITMAP hBitmap;
|
||||||
HBITMAP hMask;
|
HBITMAP hMask;
|
||||||
|
|||||||
@@ -233,6 +233,30 @@ MwLLColor MwLLAllocColor(MwLL handle, int r, int g, int b) {
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MwLLColorUpdate(MwLL handle, int r, int g, int b, MwLLColor c) {
|
||||||
|
XColor xc;
|
||||||
|
|
||||||
|
if(handle->red_mask == 0) {
|
||||||
|
if(r > 255) r = 255;
|
||||||
|
if(g > 255) g = 255;
|
||||||
|
if(b > 255) b = 255;
|
||||||
|
if(r < 0) r = 0;
|
||||||
|
if(g < 0) g = 0;
|
||||||
|
if(b < 0) b = 0;
|
||||||
|
|
||||||
|
xc.red = 256 * r;
|
||||||
|
xc.green = 256 * g;
|
||||||
|
xc.blue = 256 * b;
|
||||||
|
XAllocColor(handle->display, handle->colormap, &xc);
|
||||||
|
|
||||||
|
c->pixel = xc.pixel;
|
||||||
|
} else {
|
||||||
|
c->pixel = generate_color(handle, r, g, b);
|
||||||
|
}
|
||||||
|
c->red = r;
|
||||||
|
c->green = g;
|
||||||
|
c->blue = b;
|
||||||
|
}
|
||||||
void MwLLGetXYWH(MwLL handle, int* x, int* y, unsigned int* w, unsigned int* h) {
|
void MwLLGetXYWH(MwLL handle, int* x, int* y, unsigned int* w, unsigned int* h) {
|
||||||
Window root;
|
Window root;
|
||||||
unsigned int border, depth;
|
unsigned int border, depth;
|
||||||
@@ -435,6 +459,9 @@ MwLLPixmap MwLLCreatePixmap(MwLL handle, unsigned char* data, int width, int hei
|
|||||||
int evbase, erbase;
|
int evbase, erbase;
|
||||||
XWindowAttributes attr;
|
XWindowAttributes attr;
|
||||||
|
|
||||||
|
r->data_buf = malloc(sizeof(unsigned long) * width * height);
|
||||||
|
memcpy(r->data_buf, data, sizeof(unsigned long) * width * height);
|
||||||
|
|
||||||
XGetWindowAttributes(handle->display, handle->window, &attr);
|
XGetWindowAttributes(handle->display, handle->window, &attr);
|
||||||
|
|
||||||
r->depth = attr.depth;
|
r->depth = attr.depth;
|
||||||
@@ -448,29 +475,38 @@ MwLLPixmap MwLLCreatePixmap(MwLL handle, unsigned char* data, int width, int hei
|
|||||||
r->image = XCreateImage(handle->display, DefaultVisual(handle->display, DefaultScreen(handle->display)), r->depth, ZPixmap, 0, di, width, height, 32, width * 4);
|
r->image = XCreateImage(handle->display, DefaultVisual(handle->display, DefaultScreen(handle->display)), r->depth, ZPixmap, 0, di, width, height, 32, width * 4);
|
||||||
r->mask = XCreateImage(handle->display, DefaultVisual(handle->display, DefaultScreen(handle->display)), 1, ZPixmap, 0, dm, width, height, 32, width * 4);
|
r->mask = XCreateImage(handle->display, DefaultVisual(handle->display, DefaultScreen(handle->display)), 1, ZPixmap, 0, dm, width, height, 32, width * 4);
|
||||||
|
|
||||||
for(y = 0; y < height; y++) {
|
MwLLPixmapUpdate(handle, r);
|
||||||
for(x = 0; x < width; x++) {
|
return r;
|
||||||
unsigned char* px = &data[(y * width + x) * 4];
|
}
|
||||||
MwLLColor c = MwLLAllocColor(handle, px[0], px[1], px[2]);
|
|
||||||
unsigned long p = c->pixel;
|
|
||||||
|
|
||||||
MwLLFreeColor(c);
|
void MwLLPixmapUpdate(MwLL handle, MwLLPixmap r) {
|
||||||
|
int y, x;
|
||||||
|
MwLLColor c = NULL;
|
||||||
|
for(y = 0; y < r->height; y++) {
|
||||||
|
for(x = 0; x < r->width; x++) {
|
||||||
|
unsigned char* px = &r->data_buf[(y * r->width + x) * 4];
|
||||||
|
if(c == NULL) {
|
||||||
|
c = MwLLAllocColor(handle, px[0], px[1], px[2]);
|
||||||
|
} else {
|
||||||
|
MwLLColorUpdate(handle, px[0], px[1], px[2], c);
|
||||||
|
}
|
||||||
|
unsigned long p = c->pixel;
|
||||||
|
|
||||||
XPutPixel(r->image, x, y, p);
|
XPutPixel(r->image, x, y, p);
|
||||||
*(unsigned long*)(&r->data[(y * width + x) * sizeof(unsigned long)]) = (px[3] << 24) | p;
|
*(unsigned long*)(&r->data[(y * r->width + x) * sizeof(unsigned long)]) = (px[3] << 24) | p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(y = 0; y < height; y++) {
|
MwLLFreeColor(c);
|
||||||
for(x = 0; x < width; x++) {
|
|
||||||
if(data[(y * width + x) * 4 + 3]) {
|
for(y = 0; y < r->height; y++) {
|
||||||
|
for(x = 0; x < r->width; x++) {
|
||||||
|
if(r->data_buf[(y * r->width + x) * 4 + 3]) {
|
||||||
XPutPixel(r->mask, x, y, 1);
|
XPutPixel(r->mask, x, y, 1);
|
||||||
} else {
|
} else {
|
||||||
XPutPixel(r->mask, x, y, 0);
|
XPutPixel(r->mask, x, y, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MwLLDestroyPixmap(MwLLPixmap pixmap) {
|
void MwLLDestroyPixmap(MwLLPixmap pixmap) {
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ struct _MwLLPixmap {
|
|||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
unsigned char* data;
|
unsigned char* data;
|
||||||
|
unsigned char* data_buf;
|
||||||
|
|
||||||
int depth;
|
int depth;
|
||||||
|
|
||||||
|
|||||||
@@ -4,126 +4,155 @@
|
|||||||
#include "color_picker.h"
|
#include "color_picker.h"
|
||||||
#include <Mw/LowLevelMath.h>
|
#include <Mw/LowLevelMath.h>
|
||||||
|
|
||||||
static MwRGB hsv2rgb(MwHSV in) {
|
static void hsv2rgb(MwU32 h, MwU32 s, MwU32 v, MwU32* r, MwU32* g, MwU32* b) {
|
||||||
MwRGB out;
|
uint8_t sextant = h >> 8;
|
||||||
|
|
||||||
int i = (int)(floor(in.h * 6));
|
#define HSV_SWAPPTR(a, b) \
|
||||||
double f = in.h * 6 - i;
|
do { \
|
||||||
double p = in.v * (1 - in.s);
|
MwU32* tmp = a; \
|
||||||
double q = in.v * (1 - f * in.s);
|
a = b; \
|
||||||
double t = in.v * (1 - (1 - f) * in.s);
|
b = tmp; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
switch(i % 6) {
|
if(sextant & 2) {
|
||||||
case 0:
|
HSV_SWAPPTR(r, b);
|
||||||
out.r = in.v, out.g = t, out.b = p;
|
}
|
||||||
break;
|
if(sextant & 4) {
|
||||||
case 1:
|
|
||||||
out.r = q, out.g = in.v, out.b = p;
|
HSV_SWAPPTR(g, b);
|
||||||
break;
|
}
|
||||||
case 2:
|
if(!(sextant & 6)) {
|
||||||
out.r = p, out.g = in.v, out.b = t;
|
if(!(sextant & 1)) {
|
||||||
break;
|
HSV_SWAPPTR(r, g);
|
||||||
case 3:
|
}
|
||||||
out.r = p, out.g = q, out.b = in.v;
|
} else {
|
||||||
break;
|
if(sextant & 1) {
|
||||||
case 4:
|
HSV_SWAPPTR(r, g);
|
||||||
out.r = t, out.g = p, out.b = in.v;
|
}
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
out.r = in.v, out.g = p, out.b = q;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
*g = v; // Top level
|
||||||
|
|
||||||
|
// Perform actual calculations
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bottom level: v * (1.0 - s)
|
||||||
|
* --> (v * (255 - s) + error_corr + 1) / 256
|
||||||
|
*/
|
||||||
|
uint16_t ww; // Intermediate result
|
||||||
|
ww = v * (255 - (s)); // We don't use ~s to prevent size-promotion side effects
|
||||||
|
ww += 1; // Error correction
|
||||||
|
ww += ww >> 8; // Error correction
|
||||||
|
*b = ww >> 8;
|
||||||
|
|
||||||
|
MwU32 h_fraction = h & 0xff; // 0...255
|
||||||
|
MwU32 d; // Intermediate result
|
||||||
|
|
||||||
|
if(!(sextant & 1)) {
|
||||||
|
// *r = ...slope_up...;
|
||||||
|
d = v * (MwU32)((0xff << 8) - (MwU16)(s * (0xff - h_fraction)));
|
||||||
|
*r = d >> 16;
|
||||||
|
} else {
|
||||||
|
// *r = ...slope_down...;
|
||||||
|
d = v * (MwU32)((0xff << 8) - (MwU16)(s * h_fraction));
|
||||||
|
*r = d >> 16;
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void color_picker_wheel_image_update(color_picker* picker) {
|
static void color_picker_image_update(color_picker* picker) {
|
||||||
int y, x;
|
int y, x;
|
||||||
|
double h;
|
||||||
for(y = 0; y < PICKER_SIZE; y++) {
|
for(y = 0; y < PICKER_SIZE; y++) {
|
||||||
for(x = 0; x < PICKER_SIZE; x++) {
|
for(x = 0; x < PICKER_SIZE; x++) {
|
||||||
int i = ((y * PICKER_SIZE) + x) * 4;
|
int i = ((y * PICKER_SIZE) + x) * 4;
|
||||||
int _x = x - (PICKER_SIZE / 2);
|
int _x = x - (PICKER_SIZE / 2);
|
||||||
int _y = y - (PICKER_SIZE / 2);
|
int _y = y - (PICKER_SIZE / 2);
|
||||||
|
|
||||||
double dist = sqrt(_x * _x + _y * _y);
|
if(picker->dist_table[y][x] == 0) {
|
||||||
|
picker->dist_table[y][x] = sqrt(_x * _x + _y * _y);
|
||||||
|
}
|
||||||
|
double dist = picker->dist_table[y][x];
|
||||||
|
|
||||||
if(dist >= 180.) {
|
if(dist >= 180.) {
|
||||||
picker->inner.color_picker_image_data[i] = 0;
|
picker->color_picker_image_data[i] = 0;
|
||||||
picker->inner.color_picker_image_data[i + 1] = 0;
|
picker->color_picker_image_data[i + 1] = 0;
|
||||||
picker->inner.color_picker_image_data[i + 2] = 0;
|
picker->color_picker_image_data[i + 2] = 0;
|
||||||
picker->inner.color_picker_image_data[i + 3] = 0;
|
picker->color_picker_image_data[i + 3] = 0;
|
||||||
} else {
|
} else {
|
||||||
double xd = (M_PI / 180.) * ((double)_x);
|
|
||||||
double yd = (M_PI / 180.) * ((double)_y);
|
|
||||||
|
|
||||||
float angle = atan2(yd, xd) - M_PI;
|
|
||||||
float hue = (angle * 180.) / M_PI;
|
|
||||||
|
|
||||||
MwHSV hsv_v;
|
MwHSV hsv_v;
|
||||||
MwRGB color;
|
if(picker->hue_table[y][x].generated == 0) {
|
||||||
|
double xd = (M_PI / 180.) * ((double)_x);
|
||||||
|
double yd = (M_PI / 180.) * ((double)_y);
|
||||||
|
|
||||||
if(hue < 0.0) {
|
float angle = atan2(yd, xd) - M_PI;
|
||||||
hue += 360;
|
float hue = (angle * 180.) / M_PI;
|
||||||
|
|
||||||
|
if(hue < 0.0) {
|
||||||
|
hue += 360;
|
||||||
|
}
|
||||||
|
hsv_v.h = (hue) * (HSV_HUE_STEPS / 360.);
|
||||||
|
hsv_v.s = (dist) * (HSV_SAT_MAX / 180.);
|
||||||
|
picker->hue_table[y][x] = hsv_v;
|
||||||
|
picker->hue_table[y][x].generated = 1;
|
||||||
}
|
}
|
||||||
hsv_v.h = hue / 360.;
|
|
||||||
hsv_v.s = (dist / 179.61);
|
|
||||||
hsv_v.v = picker->inner.value;
|
|
||||||
color = hsv2rgb(hsv_v);
|
|
||||||
|
|
||||||
picker->inner.color_picker_image_data[i] = color.r * 255;
|
hsv_v = picker->hue_table[y][x];
|
||||||
picker->inner.color_picker_image_data[i + 1] = color.g * 255;
|
hsv_v.v = HSV_VAL_MAX - (picker->value * HSV_VAL_MAX);
|
||||||
picker->inner.color_picker_image_data[i + 2] = color.b * 255;
|
|
||||||
|
|
||||||
picker->inner.color_picker_image_data[i + 3] = 255;
|
MwRGB color;
|
||||||
|
hsv2rgb(hsv_v.h, hsv_v.s, hsv_v.v, &color.r, &color.g, &color.b);
|
||||||
|
|
||||||
|
picker->color_picker_image_data[i] = color.r;
|
||||||
|
picker->color_picker_image_data[i + 1] = color.g;
|
||||||
|
picker->color_picker_image_data[i + 2] = color.b;
|
||||||
|
|
||||||
|
picker->color_picker_image_data[i + 3] = 255;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(picker->inner.color_picker_pixmap != NULL) {
|
if(picker->color_picker_pixmap == NULL) {
|
||||||
MwLLDestroyPixmap(picker->inner.color_picker_pixmap);
|
picker->color_picker_pixmap = MwLoadRaw(
|
||||||
|
picker->parent, picker->color_picker_image_data, PICKER_SIZE, PICKER_SIZE);
|
||||||
|
} else {
|
||||||
|
MwReloadRaw(
|
||||||
|
picker->parent, picker->color_picker_image_data, PICKER_SIZE, PICKER_SIZE, picker->color_picker_pixmap);
|
||||||
}
|
}
|
||||||
picker->inner.color_picker_pixmap = MwLoadRaw(
|
MwVaApply(picker->color_picker_img, MwNpixmap, picker->color_picker_pixmap, NULL);
|
||||||
picker->inner.parent, picker->inner.color_picker_image_data, PICKER_SIZE, PICKER_SIZE);
|
|
||||||
MwVaApply(picker->inner.color_picker_img, MwNpixmap, picker->inner.color_picker_pixmap, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void color_picker_click(MwWidget handle, void* user, void* call) {
|
static void color_picker_click(MwWidget handle, void* user, void* call) {
|
||||||
color_picker* picker = (color_picker*)user;
|
color_picker* picker = (color_picker*)user;
|
||||||
MwLLMouse* mouse = (MwLLMouse*)call;
|
MwLLMouse* mouse = (MwLLMouse*)call;
|
||||||
char* hexColor;
|
char hexColor[8];
|
||||||
int i, r, g, b, a;
|
int i;
|
||||||
char* fgColor;
|
char fgColor[8];
|
||||||
int fr, fg, fb;
|
int fr, fg, fb;
|
||||||
|
|
||||||
(void)handle;
|
(void)handle;
|
||||||
(void)user;
|
(void)user;
|
||||||
(void)call;
|
(void)call;
|
||||||
|
|
||||||
color_picker_wheel_image_update(picker);
|
color_picker_image_update(picker);
|
||||||
|
|
||||||
i = ((mouse->point.y * PICKER_SIZE) + mouse->point.x) * 4;
|
i = ((mouse->point.y * PICKER_SIZE) + mouse->point.x) * 4;
|
||||||
|
|
||||||
r = picker->inner.color_picker_image_data[i];
|
picker->chosen_color.r = picker->color_picker_image_data[i];
|
||||||
g = picker->inner.color_picker_image_data[i + 1];
|
picker->chosen_color.g = picker->color_picker_image_data[i + 1];
|
||||||
b = picker->inner.color_picker_image_data[i + 2];
|
picker->chosen_color.b = picker->color_picker_image_data[i + 2];
|
||||||
a = picker->inner.color_picker_image_data[i + 3];
|
|
||||||
|
|
||||||
(void)a;
|
sprintf(hexColor, "#%02X%02X%02X", picker->chosen_color.r, picker->chosen_color.g, picker->chosen_color.b);
|
||||||
|
|
||||||
hexColor = malloc(8);
|
fr = picker->chosen_color.r > 128 ? 0 : 255;
|
||||||
fgColor = malloc(8);
|
fg = picker->chosen_color.g > 128 ? 0 : 255;
|
||||||
sprintf(hexColor, "#%02X%02X%02X", r, g, b);
|
fb = picker->chosen_color.b > 128 ? 0 : 255;
|
||||||
|
|
||||||
fr = r > 128 ? 0 : 255;
|
|
||||||
fg = g > 128 ? 0 : 255;
|
|
||||||
fb = b > 128 ? 0 : 255;
|
|
||||||
|
|
||||||
sprintf(fgColor, "#%02X%02X%02X", fr, fg, fb);
|
sprintf(fgColor, "#%02X%02X%02X", fr, fg, fb);
|
||||||
MwSetText(picker->inner.color_display, MwNbackground, hexColor);
|
MwSetText(picker->color_display, MwNbackground, hexColor);
|
||||||
MwSetText(picker->inner.color_display_text, MwNforeground, fgColor);
|
MwSetText(picker->color_display_text, MwNforeground, fgColor);
|
||||||
|
|
||||||
MwSetText(picker->inner.color_display_text, MwNbackground, hexColor);
|
MwSetText(picker->color_display_text, MwNbackground, hexColor);
|
||||||
MwSetText(picker->inner.color_display_text, MwNtext, hexColor);
|
MwSetText(picker->color_display_text, MwNtext, hexColor);
|
||||||
free(hexColor);
|
|
||||||
}
|
}
|
||||||
static void color_picker_on_change_value(MwWidget handle, void* user,
|
static void color_picker_on_change_value(MwWidget handle, void* user,
|
||||||
void* call) {
|
void* call) {
|
||||||
@@ -135,48 +164,75 @@ static void color_picker_on_change_value(MwWidget handle, void* user,
|
|||||||
(void)diff;
|
(void)diff;
|
||||||
(void)call;
|
(void)call;
|
||||||
|
|
||||||
picker->inner.value = 1.0 - ((double)value / 1024.);
|
picker->value = ((double)value / 1024.);
|
||||||
|
|
||||||
color_picker_wheel_image_update(picker);
|
color_picker_image_update(picker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void color_picker_destroy(color_picker* picker) {
|
||||||
|
free(picker->color_picker_image_data);
|
||||||
|
MwLLDestroyPixmap(picker->color_picker_pixmap);
|
||||||
|
|
||||||
|
MwDestroyWidget(picker->color_display_text);
|
||||||
|
MwDestroyWidget(picker->color_display);
|
||||||
|
MwDestroyWidget(picker->value_slider);
|
||||||
|
MwDestroyWidget(picker->color_picker_img);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void color_picker_close(MwWidget handle, void* user,
|
||||||
|
void* call) {
|
||||||
|
color_picker* picker = (color_picker*)user;
|
||||||
|
color_picker_destroy(picker);
|
||||||
|
MwDestroyWidget(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void color_picker_finish(MwWidget handle, void* user,
|
||||||
|
void* call) {
|
||||||
|
color_picker* picker = (color_picker*)user;
|
||||||
|
|
||||||
|
picker->cb(picker->chosen_color);
|
||||||
|
|
||||||
|
color_picker_destroy(picker);
|
||||||
|
MwDestroyWidget(handle->parent);
|
||||||
|
}
|
||||||
|
|
||||||
color_picker* color_picker_setup(MwWidget parent, int w, int h) {
|
color_picker* color_picker_setup(MwWidget parent, int w, int h) {
|
||||||
color_picker* picker = malloc(sizeof(color_picker));
|
color_picker* picker = malloc(sizeof(color_picker));
|
||||||
memset(picker, 0, sizeof(color_picker));
|
memset(picker, 0, sizeof(color_picker));
|
||||||
|
|
||||||
picker->inner.parent = parent;
|
picker->parent = parent;
|
||||||
|
|
||||||
picker->inner.color_picker_img =
|
picker->color_picker_img =
|
||||||
MwVaCreateWidget(MwImageClass, "image", picker->inner.parent, IMG_POS_X(w), IMG_POS_Y(h),
|
MwVaCreateWidget(MwImageClass, "image", picker->parent, IMG_POS_X(w), IMG_POS_Y(h),
|
||||||
PICKER_SIZE, PICKER_SIZE, NULL);
|
PICKER_SIZE, PICKER_SIZE, NULL);
|
||||||
|
|
||||||
picker->inner.color_picker_image_data = malloc(PICKER_SIZE * PICKER_SIZE * 4);
|
picker->color_picker_image_data = malloc(PICKER_SIZE * PICKER_SIZE * 4);
|
||||||
picker->inner.color_display_image_data =
|
|
||||||
malloc(PICKER_SIZE * COLOR_DISPLAY_HEIGHT * 4);
|
|
||||||
|
|
||||||
picker->inner.color_picker_pixmap = NULL;
|
picker->color_picker_pixmap = NULL;
|
||||||
picker->inner.color_display_pixmap = NULL;
|
picker->value = 0;
|
||||||
picker->inner.value = 1;
|
|
||||||
|
|
||||||
color_picker_wheel_image_update(picker);
|
color_picker_image_update(picker);
|
||||||
|
|
||||||
MwAddUserHandler(picker->inner.color_picker_img, MwNmouseDownHandler,
|
MwAddUserHandler(picker->color_picker_img, MwNmouseDownHandler,
|
||||||
color_picker_click, picker);
|
color_picker_click, picker);
|
||||||
|
|
||||||
picker->inner.color_display = MwCreateWidget(
|
picker->color_display = MwCreateWidget(
|
||||||
MwFrameClass, "colorDisplayFrame", picker->inner.parent, IMG_POS_X(w),
|
MwFrameClass, "colorDisplayFrame", picker->parent, IMG_POS_X(w),
|
||||||
IMG_POS_Y(h) + PICKER_SIZE + MARGIN, PICKER_SIZE, PICKER_SIZE / 16);
|
IMG_POS_Y(h) - (PICKER_SIZE / 16) - MARGIN, PICKER_SIZE, PICKER_SIZE / 16);
|
||||||
MwSetText(picker->inner.color_display, MwNbackground, "#000000");
|
MwSetText(picker->color_display, MwNbackground, "#FFFFFF");
|
||||||
MwSetInteger(picker->inner.color_display, MwnhasBorder, 1);
|
MwSetInteger(picker->color_display, MwnhasBorder, 1);
|
||||||
MwSetInteger(picker->inner.color_display, MwNinverted, 1);
|
MwSetInteger(picker->color_display, MwNinverted, 1);
|
||||||
|
|
||||||
picker->inner.color_display_text = MwCreateWidget(
|
picker->color_display_text = MwCreateWidget(
|
||||||
MwLabelClass, "colorDisplayFrameText", picker->inner.color_display,
|
MwLabelClass, "colorDisplayFrameText", picker->color_display,
|
||||||
MwDefaultBorderWidth(parent), MwDefaultBorderWidth(parent),
|
MwDefaultBorderWidth(parent), MwDefaultBorderWidth(parent),
|
||||||
PICKER_SIZE - MwDefaultBorderWidth(parent),
|
PICKER_SIZE - MwDefaultBorderWidth(parent),
|
||||||
(PICKER_SIZE / 16) - (MwDefaultBorderWidth(parent) * 2));
|
(PICKER_SIZE / 16) - (MwDefaultBorderWidth(parent) * 2));
|
||||||
|
|
||||||
picker->inner.value_slider = MwVaCreateWidget(
|
MwSetText(picker->color_display_text, MwNtext, "#FFFFFF");
|
||||||
MwScrollBarClass, "value-slider", picker->inner.parent,
|
|
||||||
|
picker->value_slider = MwVaCreateWidget(
|
||||||
|
MwScrollBarClass, "value-slider", picker->parent,
|
||||||
// x
|
// x
|
||||||
IMG_POS_X(w) + PICKER_SIZE + MARGIN,
|
IMG_POS_X(w) + PICKER_SIZE + MARGIN,
|
||||||
|
|
||||||
@@ -191,40 +247,42 @@ color_picker* color_picker_setup(MwWidget parent, int w, int h) {
|
|||||||
|
|
||||||
MwNorientation, MwVERTICAL, MwNminValue, 0, MwNmaxValue, 1024, NULL);
|
MwNorientation, MwVERTICAL, MwNminValue, 0, MwNmaxValue, 1024, NULL);
|
||||||
|
|
||||||
MwAddUserHandler(picker->inner.value_slider, MwNchangedHandler,
|
MwAddUserHandler(picker->value_slider, MwNchangedHandler,
|
||||||
color_picker_on_change_value, picker);
|
color_picker_on_change_value, picker);
|
||||||
|
|
||||||
|
picker->finish = MwCreateWidget(
|
||||||
|
MwButtonClass, "colorPickerFinish", picker->parent, IMG_POS_X(w),
|
||||||
|
IMG_POS_Y(h) + PICKER_SIZE + MARGIN, PICKER_SIZE, PICKER_SIZE / 8);
|
||||||
|
MwSetText(picker->finish, MwNtext, "Select");
|
||||||
|
MwSetInteger(picker->finish, MwnhasBorder, 1);
|
||||||
|
MwSetInteger(picker->finish, MwNinverted, 1);
|
||||||
|
|
||||||
|
MwAddUserHandler(picker->finish, MwNactivateHandler,
|
||||||
|
color_picker_finish, picker);
|
||||||
|
|
||||||
|
memset(picker->dist_table, 0, sizeof(picker->dist_table));
|
||||||
|
memset(picker->hue_table, 0, sizeof(picker->hue_table));
|
||||||
|
|
||||||
return picker;
|
return picker;
|
||||||
};
|
};
|
||||||
|
MwWidget MwColorPicker(MwWidget handle, const char* title, MwColorPickerCallback cb) {
|
||||||
MwWidget MwColorPicker(MwWidget handle, const char* title) {
|
|
||||||
MwPoint p;
|
MwPoint p;
|
||||||
color_picker* wheel;
|
color_picker* wheel;
|
||||||
MwWidget window;
|
MwWidget window;
|
||||||
int ww, wh;
|
|
||||||
|
|
||||||
// remove later
|
|
||||||
MwLLVec test_1 = MwLLVecU32x2(2, 5);
|
|
||||||
MwLLVec test_2 = MwLLVecU32x2(2, 12);
|
|
||||||
MwLLVec test_out = MwLLVecU32x2(0, 0);
|
|
||||||
|
|
||||||
MwLLMathAdd(&test_1, &test_2, &test_out);
|
|
||||||
|
|
||||||
printf("simd result:\n");
|
|
||||||
printf("%d + %d = %d\n", test_1.un.u32.a, test_2.un.u32.a, test_out.un.u32.a);
|
|
||||||
printf("%d + %d = %d\n", test_1.un.u32.b, test_2.un.u32.b, test_out.un.u32.b);
|
|
||||||
|
|
||||||
ww = MwGetInteger(handle, MwNwidth);
|
|
||||||
wh = MwGetInteger(handle, MwNheight);
|
|
||||||
p.x = p.y = 0;
|
p.x = p.y = 0;
|
||||||
|
|
||||||
window = MwVaCreateWidget(MwWindowClass, "main", handle, MwDEFAULT, MwDEFAULT,
|
window = MwVaCreateWidget(MwWindowClass, "main", handle, MwDEFAULT, MwDEFAULT,
|
||||||
ww, wh, MwNtitle, title, NULL);
|
WIN_SIZE, WIN_SIZE, MwNtitle, title, NULL);
|
||||||
|
|
||||||
wheel = color_picker_setup(window, ww, wh);
|
wheel = color_picker_setup(window, WIN_SIZE, WIN_SIZE);
|
||||||
|
|
||||||
|
MwAddUserHandler(window, MwNcloseHandler, color_picker_close, wheel);
|
||||||
|
|
||||||
MwLLDetach(window->lowlevel, &p);
|
MwLLDetach(window->lowlevel, &p);
|
||||||
MwLLMakePopup(window->lowlevel, handle->lowlevel);
|
MwLLMakePopup(window->lowlevel, handle->lowlevel);
|
||||||
|
|
||||||
|
wheel->cb = cb;
|
||||||
|
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include <Mw/ColorPicker.h>
|
#include <Mw/ColorPicker.h>
|
||||||
#include <Mw/Milsko.h>
|
#include <Mw/Milsko.h>
|
||||||
|
|
||||||
|
#define WIN_SIZE 512
|
||||||
#define PICKER_SIZE 360
|
#define PICKER_SIZE 360
|
||||||
#define IMG_POS_X(w) ((w - PICKER_SIZE) / 2)
|
#define IMG_POS_X(w) ((w - PICKER_SIZE) / 2)
|
||||||
#define IMG_POS_Y(h) ((h - PICKER_SIZE) / 2)
|
#define IMG_POS_Y(h) ((h - PICKER_SIZE) / 2)
|
||||||
@@ -13,31 +14,42 @@
|
|||||||
#define MARGIN (PICKER_SIZE / 32)
|
#define MARGIN (PICKER_SIZE / 32)
|
||||||
#define COLOR_DISPLAY_HEIGHT 12
|
#define COLOR_DISPLAY_HEIGHT 12
|
||||||
|
|
||||||
|
#define HSV_HUE_SEXTANT 256.
|
||||||
|
#define HSV_HUE_STEPS (6. * HSV_HUE_SEXTANT)
|
||||||
|
|
||||||
|
#define HSV_HUE_MIN 0.
|
||||||
|
#define HSV_HUE_MAX (HSV_HUE_STEPS - 1.)
|
||||||
|
#define HSV_SAT_MIN 0.
|
||||||
|
#define HSV_SAT_MAX 255.
|
||||||
|
#define HSV_VAL_MIN 0.
|
||||||
|
#define HSV_VAL_MAX 255.
|
||||||
|
|
||||||
typedef struct _color_picker color_picker;
|
typedef struct _color_picker color_picker;
|
||||||
typedef struct _color_picker_inner color_picker_inner;
|
|
||||||
typedef struct _color_picker_vtable color_picker_vtable;
|
typedef struct _color_picker_vtable color_picker_vtable;
|
||||||
|
typedef struct _MwHSV MwHSV;
|
||||||
|
|
||||||
struct _color_picker_inner {
|
struct _MwHSV {
|
||||||
MwWidget parent;
|
double h; // angle in degrees
|
||||||
MwWidget color_picker_img;
|
double s; // a fraction between 0 and 1
|
||||||
MwWidget value_slider;
|
double v; // a fraction between 0 and 1
|
||||||
MwWidget color_display;
|
MwBool generated;
|
||||||
MwWidget color_display_text;
|
|
||||||
MwLLPixmap color_picker_pixmap;
|
|
||||||
MwLLPixmap color_display_pixmap;
|
|
||||||
double value;
|
|
||||||
unsigned char* color_picker_image_data;
|
|
||||||
unsigned char* color_display_image_data;
|
|
||||||
MwPoint point;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _color_picker_vtable {
|
|
||||||
void* reserved;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _color_picker {
|
struct _color_picker {
|
||||||
color_picker_inner inner;
|
MwWidget parent;
|
||||||
color_picker_vtable vtable;
|
MwWidget color_picker_img;
|
||||||
|
MwWidget value_slider;
|
||||||
|
MwWidget color_display;
|
||||||
|
MwWidget color_display_text;
|
||||||
|
MwWidget finish;
|
||||||
|
MwLLPixmap color_picker_pixmap;
|
||||||
|
double value;
|
||||||
|
unsigned char* color_picker_image_data;
|
||||||
|
MwPoint point;
|
||||||
|
double dist_table[PICKER_SIZE][PICKER_SIZE];
|
||||||
|
MwHSV hue_table[PICKER_SIZE][PICKER_SIZE];
|
||||||
|
MwColorPickerCallback cb;
|
||||||
|
MwRGB chosen_color;
|
||||||
};
|
};
|
||||||
|
|
||||||
color_picker* color_picker_setup(MwWidget parent, int w, int h);
|
color_picker* color_picker_setup(MwWidget parent, int w, int h);
|
||||||
|
|||||||
28
src/draw.c
28
src/draw.c
@@ -666,6 +666,34 @@ MwLLPixmap MwLoadRaw(MwWidget handle, unsigned char* rgb, int width, int height)
|
|||||||
return px;
|
return px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MwReloadRaw(MwWidget handle, unsigned char* rgb, int width, int height, MwLLPixmap px) {
|
||||||
|
int i;
|
||||||
|
MwLLColor base = handle->bgcolor == NULL ? MwParseColor(handle, MwGetText(handle, MwNbackground)) : handle->bgcolor;
|
||||||
|
|
||||||
|
memset(px->data_buf, 0, width * height * 4);
|
||||||
|
for(i = 0; i < width * height; i++) {
|
||||||
|
unsigned char* pin = &rgb[i * 4];
|
||||||
|
unsigned char* pout = &px->data_buf[i * 4];
|
||||||
|
double a = pin[3];
|
||||||
|
|
||||||
|
a /= 255;
|
||||||
|
if(a != 0) {
|
||||||
|
pout[0] = pin[0] * a;
|
||||||
|
pout[1] = pin[1] * a;
|
||||||
|
pout[2] = pin[2] * a;
|
||||||
|
|
||||||
|
pout[0] += base->red * (1 - a);
|
||||||
|
pout[1] += base->green * (1 - a);
|
||||||
|
pout[2] += base->blue * (1 - a);
|
||||||
|
pout[3] = 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(handle->bgcolor == NULL) MwLLFreeColor(base);
|
||||||
|
|
||||||
|
MwLLPixmapUpdate(handle->lowlevel, px);
|
||||||
|
}
|
||||||
|
|
||||||
void MwGetColor(MwLLColor color, int* red, int* green, int* blue) {
|
void MwGetColor(MwLLColor color, int* red, int* green, int* blue) {
|
||||||
*red = color->red;
|
*red = color->red;
|
||||||
*green = color->green;
|
*green = color->green;
|
||||||
|
|||||||
@@ -1,424 +1,110 @@
|
|||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
#include <Mw/LowLevelMath.h>
|
#include <Mw/LowLevelMath.h>
|
||||||
|
|
||||||
#include "math_internal.h"
|
#include "math_internal.h"
|
||||||
|
|
||||||
static void default_add_u8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
#define MAKE_DEFAULT_TABLE(suffix, ty) \
|
||||||
out->un.u8.a = a->un.u8.a + b->un.u8.a;
|
static void add_##suffix(MwLLVec* a, MwLLVec* b, MwLLVec* out) { \
|
||||||
out->un.u8.b = a->un.u8.b + b->un.u8.b;
|
int i = 0; \
|
||||||
out->un.u8.c = a->un.u8.c + b->un.u8.c;
|
for(; i < a->size; i++) { \
|
||||||
out->un.u8.d = a->un.u8.d + b->un.u8.d;
|
((ty*)out->buffer)[i] = ((ty*)a->buffer)[i] + ((ty*)b->buffer)[i]; \
|
||||||
out->un.u8.e = a->un.u8.e + b->un.u8.e;
|
} \
|
||||||
out->un.u8.f = a->un.u8.f + b->un.u8.f;
|
}; \
|
||||||
out->un.u8.g = a->un.u8.g + b->un.u8.g;
|
static void sub_##suffix(MwLLVec* a, MwLLVec* b, MwLLVec* out) { \
|
||||||
out->un.u8.h = a->un.u8.h + b->un.u8.h;
|
int i = 0; \
|
||||||
};
|
for(; i < a->size; i++) { \
|
||||||
static void default_sub_u8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
((ty*)out->buffer)[i] = ((ty*)a->buffer)[i] - ((ty*)b->buffer)[i]; \
|
||||||
out->un.u8.a = a->un.u8.a - b->un.u8.a;
|
} \
|
||||||
out->un.u8.b = a->un.u8.b - b->un.u8.b;
|
}; \
|
||||||
out->un.u8.c = a->un.u8.c - b->un.u8.c;
|
static void multiply_##suffix(MwLLVec* a, MwLLVec* b, MwLLVec* out) { \
|
||||||
out->un.u8.d = a->un.u8.d - b->un.u8.d;
|
int i = 0; \
|
||||||
out->un.u8.e = a->un.u8.e - b->un.u8.e;
|
for(; i < a->size; i++) { \
|
||||||
out->un.u8.f = a->un.u8.f - b->un.u8.f;
|
((ty*)out->buffer)[i] = ((ty*)a->buffer)[i] * ((ty*)b->buffer)[i]; \
|
||||||
out->un.u8.g = a->un.u8.g - b->un.u8.g;
|
} \
|
||||||
out->un.u8.h = a->un.u8.h - b->un.u8.h;
|
}; \
|
||||||
};
|
static void reciprocal_##suffix(MwLLVec* a, MwLLVec* out) { \
|
||||||
static void default_multiply_u8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
int i = 0; \
|
||||||
out->un.u8.a = a->un.u8.a * b->un.u8.a;
|
for(; i < a->size; i++) { \
|
||||||
out->un.u8.b = a->un.u8.b * b->un.u8.b;
|
((ty*)out->buffer)[i] = pow(((ty*)a->buffer)[i], -1); \
|
||||||
out->un.u8.c = a->un.u8.c * b->un.u8.c;
|
} \
|
||||||
out->un.u8.d = a->un.u8.d * b->un.u8.d;
|
}; \
|
||||||
out->un.u8.e = a->un.u8.e * b->un.u8.e;
|
static void squareRoot_##suffix(MwLLVec* a, MwLLVec* out) { \
|
||||||
out->un.u8.f = a->un.u8.f * b->un.u8.f;
|
int i = 0; \
|
||||||
out->un.u8.g = a->un.u8.g * b->un.u8.g;
|
for(; i < a->size; i++) { \
|
||||||
out->un.u8.h = a->un.u8.h * b->un.u8.h;
|
((ty*)out->buffer)[i] = sqrt(((ty*)a->buffer)[i]); \
|
||||||
};
|
} \
|
||||||
static void default_reciprocal_u8(MwLLVec* a, MwLLVec* out) {
|
} \
|
||||||
out->un.u8.a = pow(a->un.u8.a, -1);
|
static void shiftRight_##suffix(MwLLVec* a, MwLLVec* b, MwLLVec* out) { \
|
||||||
out->un.u8.b = pow(a->un.u8.b, -1);
|
int i = 0; \
|
||||||
out->un.u8.c = pow(a->un.u8.c, -1);
|
for(; i < a->size; i++) { \
|
||||||
out->un.u8.d = pow(a->un.u8.d, -1);
|
((ty*)out->buffer)[i] = ((ty*)a->buffer)[i] >> ((ty*)b->buffer)[i]; \
|
||||||
out->un.u8.e = pow(a->un.u8.e, -1);
|
} \
|
||||||
out->un.u8.f = pow(a->un.u8.f, -1);
|
}; \
|
||||||
out->un.u8.g = pow(a->un.u8.g, -1);
|
static void shiftLeft_##suffix(MwLLVec* a, MwLLVec* b, MwLLVec* out) { \
|
||||||
out->un.u8.h = pow(a->un.u8.h, -1);
|
int i = 0; \
|
||||||
};
|
for(; i < a->size; i++) { \
|
||||||
static void default_squareRoot_u8(MwLLVec* a, MwLLVec* out) {
|
((ty*)out->buffer)[i] = ((ty*)a->buffer)[i] << ((ty*)b->buffer)[i]; \
|
||||||
out->un.u8.a = sqrt(a->un.u8.a);
|
} \
|
||||||
out->un.u8.b = sqrt(a->un.u8.b);
|
} \
|
||||||
out->un.u8.c = sqrt(a->un.u8.c);
|
static void equal_##suffix(MwLLVec* a, MwLLVec* b, MwLLVec* out) { \
|
||||||
out->un.u8.d = sqrt(a->un.u8.d);
|
int i = 0; \
|
||||||
out->un.u8.e = sqrt(a->un.u8.e);
|
for(; i < a->size; i++) { \
|
||||||
out->un.u8.f = sqrt(a->un.u8.f);
|
((ty*)out->buffer)[i] = ((ty*)a->buffer)[i] == ((ty*)b->buffer)[i]; \
|
||||||
out->un.u8.g = sqrt(a->un.u8.g);
|
} \
|
||||||
out->un.u8.h = sqrt(a->un.u8.h);
|
}; \
|
||||||
}
|
static void greaterThen_##suffix(MwLLVec* a, MwLLVec* b, MwLLVec* out) { \
|
||||||
static void default_shiftRight_u8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
int i = 0; \
|
||||||
out->un.u8.a = a->un.u8.a >> b->un.u8.a;
|
for(; i < a->size; i++) { \
|
||||||
out->un.u8.b = a->un.u8.b >> b->un.u8.b;
|
((ty*)out->buffer)[i] = ((ty*)a->buffer)[i] >= ((ty*)b->buffer)[i]; \
|
||||||
out->un.u8.c = a->un.u8.c >> b->un.u8.c;
|
} \
|
||||||
out->un.u8.d = a->un.u8.d >> b->un.u8.d;
|
}; \
|
||||||
out->un.u8.e = a->un.u8.e >> b->un.u8.e;
|
static MwLLMathVTable table_##suffix = {add_##suffix, multiply_##suffix, sub_##suffix, reciprocal_##suffix, squareRoot_##suffix, NULL, NULL, shiftRight_##suffix, shiftLeft_##suffix, equal_##suffix, greaterThen_##suffix, NULL};
|
||||||
out->un.u8.f = a->un.u8.f >> b->un.u8.f;
|
|
||||||
out->un.u8.g = a->un.u8.g >> b->un.u8.g;
|
|
||||||
out->un.u8.h = a->un.u8.h >> b->un.u8.h;
|
|
||||||
};
|
|
||||||
static void default_shiftLeft_u8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
|
||||||
out->un.u8.a = a->un.u8.a << b->un.u8.a;
|
|
||||||
out->un.u8.b = a->un.u8.b << b->un.u8.b;
|
|
||||||
out->un.u8.c = a->un.u8.c << b->un.u8.c;
|
|
||||||
out->un.u8.d = a->un.u8.d << b->un.u8.d;
|
|
||||||
out->un.u8.e = a->un.u8.e << b->un.u8.e;
|
|
||||||
out->un.u8.f = a->un.u8.f << b->un.u8.f;
|
|
||||||
out->un.u8.g = a->un.u8.g << b->un.u8.g;
|
|
||||||
out->un.u8.h = a->un.u8.h << b->un.u8.h;
|
|
||||||
}
|
|
||||||
static void default_equal_u8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
|
||||||
out->un.u8.a = a->un.u8.a == b->un.u8.a;
|
|
||||||
out->un.u8.b = a->un.u8.b == b->un.u8.b;
|
|
||||||
out->un.u8.c = a->un.u8.c == b->un.u8.c;
|
|
||||||
out->un.u8.d = a->un.u8.d == b->un.u8.d;
|
|
||||||
out->un.u8.e = a->un.u8.e == b->un.u8.e;
|
|
||||||
out->un.u8.f = a->un.u8.f == b->un.u8.f;
|
|
||||||
out->un.u8.g = a->un.u8.g == b->un.u8.g;
|
|
||||||
out->un.u8.h = a->un.u8.h == b->un.u8.h;
|
|
||||||
};
|
|
||||||
static void default_greaterThen_u8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
|
||||||
out->un.u8.a = a->un.u8.a >= b->un.u8.a;
|
|
||||||
out->un.u8.b = a->un.u8.b >= b->un.u8.b;
|
|
||||||
out->un.u8.c = a->un.u8.c >= b->un.u8.c;
|
|
||||||
out->un.u8.d = a->un.u8.d >= b->un.u8.d;
|
|
||||||
out->un.u8.e = a->un.u8.e >= b->un.u8.e;
|
|
||||||
out->un.u8.f = a->un.u8.f >= b->un.u8.f;
|
|
||||||
out->un.u8.g = a->un.u8.g >= b->un.u8.g;
|
|
||||||
out->un.u8.h = a->un.u8.h >= b->un.u8.h;
|
|
||||||
};
|
|
||||||
static MwLLMathVTable table_u8 = {
|
|
||||||
default_add_u8,
|
|
||||||
default_multiply_u8,
|
|
||||||
default_sub_u8,
|
|
||||||
default_reciprocal_u8,
|
|
||||||
default_squareRoot_u8,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
default_shiftRight_u8,
|
|
||||||
default_shiftLeft_u8,
|
|
||||||
default_equal_u8,
|
|
||||||
default_greaterThen_u8,
|
|
||||||
NULL};
|
|
||||||
static void default_add_u16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
|
||||||
out->un.u16.a = a->un.u16.a + b->un.u16.a;
|
|
||||||
out->un.u16.b = a->un.u16.b + b->un.u16.b;
|
|
||||||
out->un.u16.c = a->un.u16.c + b->un.u16.c;
|
|
||||||
out->un.u16.d = a->un.u16.d + b->un.u16.d;
|
|
||||||
}
|
|
||||||
static void default_sub_u16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
|
||||||
out->un.u16.a = a->un.u16.a - b->un.u16.a;
|
|
||||||
out->un.u16.b = a->un.u16.b - b->un.u16.b;
|
|
||||||
out->un.u16.c = a->un.u16.c - b->un.u16.c;
|
|
||||||
out->un.u16.d = a->un.u16.d - b->un.u16.d;
|
|
||||||
}
|
|
||||||
static void default_multiply_u16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
|
||||||
out->un.u16.a = a->un.u16.a * b->un.u16.a;
|
|
||||||
out->un.u16.b = a->un.u16.b * b->un.u16.b;
|
|
||||||
out->un.u16.c = a->un.u16.c * b->un.u16.c;
|
|
||||||
out->un.u16.d = a->un.u16.d * b->un.u16.d;
|
|
||||||
}
|
|
||||||
static void default_reciprocal_u16(MwLLVec* a, MwLLVec* out) {
|
|
||||||
out->un.u16.a = pow(a->un.u16.a, -1);
|
|
||||||
out->un.u16.b = pow(a->un.u16.b, -1);
|
|
||||||
out->un.u16.c = pow(a->un.u16.c, -1);
|
|
||||||
out->un.u16.d = pow(a->un.u16.d, -1);
|
|
||||||
};
|
|
||||||
static void default_squareRoot_u16(MwLLVec* a, MwLLVec* out) {
|
|
||||||
out->un.u16.a = sqrt(a->un.u16.a);
|
|
||||||
out->un.u16.b = sqrt(a->un.u16.b);
|
|
||||||
out->un.u16.c = sqrt(a->un.u16.c);
|
|
||||||
out->un.u16.d = sqrt(a->un.u16.d);
|
|
||||||
};
|
|
||||||
|
|
||||||
static void default_shiftRight_u16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
MAKE_DEFAULT_TABLE(u8, MwU8);
|
||||||
out->un.u16.a = a->un.u16.a >> b->un.u16.a;
|
MAKE_DEFAULT_TABLE(u16, MwU16);
|
||||||
out->un.u16.b = a->un.u16.b >> b->un.u16.b;
|
MAKE_DEFAULT_TABLE(u32, MwU32);
|
||||||
out->un.u16.c = a->un.u16.c >> b->un.u16.c;
|
MAKE_DEFAULT_TABLE(u64, MwU64);
|
||||||
out->un.u16.d = a->un.u16.d >> b->un.u16.d;
|
MAKE_DEFAULT_TABLE(i8, MwI8);
|
||||||
};
|
MAKE_DEFAULT_TABLE(i16, MwI16);
|
||||||
static void default_shiftLeft_u16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
MAKE_DEFAULT_TABLE(i32, MwI32);
|
||||||
out->un.u16.a = a->un.u16.a << b->un.u16.a;
|
MAKE_DEFAULT_TABLE(i64, MwI64);
|
||||||
out->un.u16.b = a->un.u16.b << b->un.u16.b;
|
|
||||||
out->un.u16.c = a->un.u16.c << b->un.u16.c;
|
|
||||||
out->un.u16.d = a->un.u16.d << b->un.u16.d;
|
|
||||||
}
|
|
||||||
static void default_equal_u16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
|
||||||
out->un.u16.a = a->un.u16.a == b->un.u16.a;
|
|
||||||
out->un.u16.b = a->un.u16.b == b->un.u16.b;
|
|
||||||
out->un.u16.c = a->un.u16.c == b->un.u16.c;
|
|
||||||
out->un.u16.d = a->un.u16.d == b->un.u16.d;
|
|
||||||
}
|
|
||||||
static void default_greaterThen_u16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
|
||||||
out->un.u16.a = a->un.u16.a >= b->un.u16.a;
|
|
||||||
out->un.u16.b = a->un.u16.b >= b->un.u16.b;
|
|
||||||
out->un.u16.c = a->un.u16.c >= b->un.u16.c;
|
|
||||||
out->un.u16.d = a->un.u16.d >= b->un.u16.d;
|
|
||||||
}
|
|
||||||
static MwLLMathVTable table_u16 = {
|
|
||||||
default_add_u16,
|
|
||||||
default_multiply_u16,
|
|
||||||
default_sub_u16,
|
|
||||||
default_reciprocal_u16,
|
|
||||||
default_squareRoot_u16,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
default_shiftRight_u16,
|
|
||||||
default_shiftLeft_u16,
|
|
||||||
default_equal_u16,
|
|
||||||
default_greaterThen_u16,
|
|
||||||
NULL};
|
|
||||||
|
|
||||||
static void default_add_u32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
static MwLLMathVTable* defaultMultiTable[MwLLVecType_Max] = {
|
||||||
out->un.u32.a = a->un.u32.a + b->un.u32.a;
|
&table_u8, /*MwLLVecTypeU8*/
|
||||||
out->un.u32.b = a->un.u32.b + b->un.u32.b;
|
&table_u16, /*MwLLVecTypeU16*/
|
||||||
}
|
&table_u32, /*MwLLVecTypeU32*/
|
||||||
static void default_sub_u32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
&table_u64, /*MwLLVecTypeU64*/
|
||||||
out->un.u32.a = a->un.u32.a - b->un.u32.a;
|
&table_i8, /*MwLLVecTypeI8*/
|
||||||
out->un.u32.b = a->un.u32.b - b->un.u32.b;
|
&table_i16, /*MwLLVecTypeI16*/
|
||||||
}
|
&table_i32, /*MwLLVecTypeI32*/
|
||||||
static void default_multiply_u32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
&table_i64, /*MwLLVecTypeI64*/
|
||||||
out->un.u32.a = a->un.u32.a * b->un.u32.a;
|
|
||||||
out->un.u32.b = a->un.u32.b * b->un.u32.b;
|
|
||||||
}
|
|
||||||
static void default_reciprocal_u32(MwLLVec* a, MwLLVec* out) {
|
|
||||||
out->un.u32.a = pow(a->un.u32.a, -1);
|
|
||||||
out->un.u32.b = pow(a->un.u32.b, -1);
|
|
||||||
};
|
};
|
||||||
static void default_squareRoot_u32(MwLLVec* a, MwLLVec* out) {
|
void default_apply(MwLLVec* v) {
|
||||||
out->un.u32.a = sqrt(a->un.u32.a);
|
switch(v->ty) {
|
||||||
out->un.u32.b = sqrt(a->un.u32.b);
|
case MwLLVecTypeU8:
|
||||||
};
|
v->vtable = table_u8;
|
||||||
|
break;
|
||||||
static void default_shiftRight_u32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
case MwLLVecTypeU16:
|
||||||
out->un.u32.a = a->un.u32.a >> b->un.u32.a;
|
v->vtable = table_u16;
|
||||||
out->un.u32.b = a->un.u32.b >> b->un.u32.b;
|
break;
|
||||||
};
|
case MwLLVecTypeU32:
|
||||||
static void default_shiftLeft_u32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
v->vtable = table_u32;
|
||||||
out->un.u32.a = a->un.u32.a << b->un.u32.a;
|
break;
|
||||||
out->un.u32.b = a->un.u32.b << b->un.u32.b;
|
case MwLLVecTypeU64:
|
||||||
}
|
v->vtable = table_u64;
|
||||||
static void default_equal_u32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
break;
|
||||||
out->un.u32.a = a->un.u32.a == b->un.u32.a;
|
case MwLLVecTypeI8:
|
||||||
out->un.u32.b = a->un.u32.b == b->un.u32.b;
|
v->vtable = table_i8;
|
||||||
}
|
break;
|
||||||
static void default_greaterThen_u32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
case MwLLVecTypeI16:
|
||||||
out->un.u32.a = a->un.u32.a >= b->un.u32.a;
|
v->vtable = table_i16;
|
||||||
out->un.u32.b = a->un.u32.b >= b->un.u32.b;
|
break;
|
||||||
}
|
case MwLLVecTypeI32:
|
||||||
static MwLLMathVTable table_u32 = {
|
v->vtable = table_i32;
|
||||||
default_add_u32,
|
break;
|
||||||
default_multiply_u32,
|
case MwLLVecTypeI64:
|
||||||
default_sub_u32,
|
v->vtable = table_i64;
|
||||||
default_reciprocal_u32,
|
break;
|
||||||
default_squareRoot_u32,
|
case MwLLVecType_Max:
|
||||||
NULL,
|
break;
|
||||||
NULL,
|
}
|
||||||
default_shiftRight_u32,
|
|
||||||
default_shiftLeft_u32,
|
|
||||||
default_equal_u32,
|
|
||||||
default_greaterThen_u32,
|
|
||||||
NULL};
|
|
||||||
|
|
||||||
static void default_add_i8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
|
||||||
out->un.i8.a = a->un.i8.a + b->un.i8.a;
|
|
||||||
out->un.i8.b = a->un.i8.b + b->un.i8.b;
|
|
||||||
out->un.i8.c = a->un.i8.c + b->un.i8.c;
|
|
||||||
out->un.i8.d = a->un.i8.d + b->un.i8.d;
|
|
||||||
out->un.i8.e = a->un.i8.e + b->un.i8.e;
|
|
||||||
out->un.i8.f = a->un.i8.f + b->un.i8.f;
|
|
||||||
out->un.i8.g = a->un.i8.g + b->un.i8.g;
|
|
||||||
out->un.i8.h = a->un.i8.h + b->un.i8.h;
|
|
||||||
};
|
|
||||||
static void default_sub_i8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
|
||||||
out->un.i8.a = a->un.i8.a - b->un.i8.a;
|
|
||||||
out->un.i8.b = a->un.i8.b - b->un.i8.b;
|
|
||||||
out->un.i8.c = a->un.i8.c - b->un.i8.c;
|
|
||||||
out->un.i8.d = a->un.i8.d - b->un.i8.d;
|
|
||||||
out->un.i8.e = a->un.i8.e - b->un.i8.e;
|
|
||||||
out->un.i8.f = a->un.i8.f - b->un.i8.f;
|
|
||||||
out->un.i8.g = a->un.i8.g - b->un.i8.g;
|
|
||||||
out->un.i8.h = a->un.i8.h - b->un.i8.h;
|
|
||||||
};
|
|
||||||
static void default_multiply_i8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
|
||||||
out->un.i8.a = a->un.i8.a * b->un.i8.a;
|
|
||||||
out->un.i8.b = a->un.i8.b * b->un.i8.b;
|
|
||||||
out->un.i8.c = a->un.i8.c * b->un.i8.c;
|
|
||||||
out->un.i8.d = a->un.i8.d * b->un.i8.d;
|
|
||||||
out->un.i8.e = a->un.i8.e * b->un.i8.e;
|
|
||||||
out->un.i8.f = a->un.i8.f * b->un.i8.f;
|
|
||||||
out->un.i8.g = a->un.i8.g * b->un.i8.g;
|
|
||||||
out->un.i8.h = a->un.i8.h * b->un.i8.h;
|
|
||||||
};
|
|
||||||
static void default_reciprocal_i8(MwLLVec* a, MwLLVec* out) {
|
|
||||||
out->un.i8.a = pow(a->un.i8.a, -1);
|
|
||||||
out->un.i8.b = pow(a->un.i8.b, -1);
|
|
||||||
out->un.i8.c = pow(a->un.i8.c, -1);
|
|
||||||
out->un.i8.d = pow(a->un.i8.d, -1);
|
|
||||||
out->un.i8.e = pow(a->un.i8.e, -1);
|
|
||||||
out->un.i8.f = pow(a->un.i8.f, -1);
|
|
||||||
out->un.i8.g = pow(a->un.i8.g, -1);
|
|
||||||
out->un.i8.h = pow(a->un.i8.h, -1);
|
|
||||||
};
|
|
||||||
static void default_squareRoot_i8(MwLLVec* a, MwLLVec* out) {
|
|
||||||
out->un.i8.a = sqrt(a->un.i8.a);
|
|
||||||
out->un.i8.b = sqrt(a->un.i8.b);
|
|
||||||
out->un.i8.c = sqrt(a->un.i8.c);
|
|
||||||
out->un.i8.d = sqrt(a->un.i8.d);
|
|
||||||
out->un.i8.e = sqrt(a->un.i8.e);
|
|
||||||
out->un.i8.f = sqrt(a->un.i8.f);
|
|
||||||
out->un.i8.g = sqrt(a->un.i8.g);
|
|
||||||
out->un.i8.h = sqrt(a->un.i8.h);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void default_equal_i8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
|
||||||
out->un.i8.a = a->un.i8.a == b->un.i8.a;
|
|
||||||
out->un.i8.b = a->un.i8.b == b->un.i8.b;
|
|
||||||
out->un.i8.c = a->un.i8.c == b->un.i8.c;
|
|
||||||
out->un.i8.d = a->un.i8.d == b->un.i8.d;
|
|
||||||
out->un.i8.e = a->un.i8.e == b->un.i8.e;
|
|
||||||
out->un.i8.f = a->un.i8.f == b->un.i8.f;
|
|
||||||
out->un.i8.g = a->un.i8.g == b->un.i8.g;
|
|
||||||
out->un.i8.h = a->un.i8.h == b->un.i8.h;
|
|
||||||
};
|
|
||||||
static void default_greaterThen_i8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
|
||||||
out->un.i8.a = a->un.i8.a >= b->un.i8.a;
|
|
||||||
out->un.i8.b = a->un.i8.b >= b->un.i8.b;
|
|
||||||
out->un.i8.c = a->un.i8.c >= b->un.i8.c;
|
|
||||||
out->un.i8.d = a->un.i8.d >= b->un.i8.d;
|
|
||||||
out->un.i8.e = a->un.i8.e >= b->un.i8.e;
|
|
||||||
out->un.i8.f = a->un.i8.f >= b->un.i8.f;
|
|
||||||
out->un.i8.g = a->un.i8.g >= b->un.i8.g;
|
|
||||||
out->un.i8.h = a->un.i8.h >= b->un.i8.h;
|
|
||||||
};
|
|
||||||
static MwLLMathVTable table_i8 = {
|
|
||||||
default_add_i8,
|
|
||||||
default_multiply_i8,
|
|
||||||
default_sub_i8,
|
|
||||||
default_reciprocal_i8,
|
|
||||||
default_squareRoot_i8,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
default_shiftRight_u8,
|
|
||||||
default_shiftLeft_u8,
|
|
||||||
default_equal_i8,
|
|
||||||
default_greaterThen_i8,
|
|
||||||
NULL};
|
|
||||||
static void default_add_i16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
|
||||||
out->un.i16.a = a->un.i16.a + b->un.i16.a;
|
|
||||||
out->un.i16.b = a->un.i16.b + b->un.i16.b;
|
|
||||||
out->un.i16.c = a->un.i16.c + b->un.i16.c;
|
|
||||||
out->un.i16.d = a->un.i16.d + b->un.i16.d;
|
|
||||||
}
|
|
||||||
static void default_sub_i16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
|
||||||
out->un.i16.a = a->un.i16.a - b->un.i16.a;
|
|
||||||
out->un.i16.b = a->un.i16.b - b->un.i16.b;
|
|
||||||
out->un.i16.c = a->un.i16.c - b->un.i16.c;
|
|
||||||
out->un.i16.d = a->un.i16.d - b->un.i16.d;
|
|
||||||
}
|
|
||||||
static void default_multiply_i16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
|
||||||
out->un.i16.a = a->un.i16.a * b->un.i16.a;
|
|
||||||
out->un.i16.b = a->un.i16.b * b->un.i16.b;
|
|
||||||
out->un.i16.c = a->un.i16.c * b->un.i16.c;
|
|
||||||
out->un.i16.d = a->un.i16.d * b->un.i16.d;
|
|
||||||
}
|
|
||||||
static void default_reciprocal_i16(MwLLVec* a, MwLLVec* out) {
|
|
||||||
out->un.i16.a = pow(a->un.i16.a, -1);
|
|
||||||
out->un.i16.b = pow(a->un.i16.b, -1);
|
|
||||||
out->un.i16.c = pow(a->un.i16.c, -1);
|
|
||||||
out->un.i16.d = pow(a->un.i16.d, -1);
|
|
||||||
};
|
|
||||||
static void default_squareRoot_i16(MwLLVec* a, MwLLVec* out) {
|
|
||||||
out->un.i16.a = sqrt(a->un.i16.a);
|
|
||||||
out->un.i16.b = sqrt(a->un.i16.b);
|
|
||||||
out->un.i16.c = sqrt(a->un.i16.c);
|
|
||||||
out->un.i16.d = sqrt(a->un.i16.d);
|
|
||||||
};
|
|
||||||
|
|
||||||
static void default_equal_i16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
|
||||||
out->un.i16.a = a->un.i16.a == b->un.i16.a;
|
|
||||||
out->un.i16.b = a->un.i16.b == b->un.i16.b;
|
|
||||||
out->un.i16.c = a->un.i16.c == b->un.i16.c;
|
|
||||||
out->un.i16.d = a->un.i16.d == b->un.i16.d;
|
|
||||||
}
|
|
||||||
static void default_greaterThen_i16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
|
||||||
out->un.i16.a = a->un.i16.a >= b->un.i16.a;
|
|
||||||
out->un.i16.b = a->un.i16.b >= b->un.i16.b;
|
|
||||||
out->un.i16.c = a->un.i16.c >= b->un.i16.c;
|
|
||||||
out->un.i16.d = a->un.i16.d >= b->un.i16.d;
|
|
||||||
}
|
|
||||||
static MwLLMathVTable table_i16 = {
|
|
||||||
default_add_i16,
|
|
||||||
default_multiply_i16,
|
|
||||||
default_sub_i16,
|
|
||||||
default_reciprocal_i16,
|
|
||||||
default_squareRoot_i16,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
default_shiftRight_u16,
|
|
||||||
default_shiftLeft_u16,
|
|
||||||
default_equal_i16,
|
|
||||||
default_greaterThen_i16,
|
|
||||||
NULL};
|
|
||||||
|
|
||||||
static void default_add_i32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
|
||||||
out->un.i32.a = a->un.i32.a + b->un.i32.a;
|
|
||||||
out->un.i32.b = a->un.i32.b + b->un.i32.b;
|
|
||||||
}
|
|
||||||
static void default_sub_i32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
|
||||||
out->un.i32.a = a->un.i32.a - b->un.i32.a;
|
|
||||||
out->un.i32.b = a->un.i32.b - b->un.i32.b;
|
|
||||||
}
|
|
||||||
static void default_multiply_i32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
|
||||||
out->un.i32.a = a->un.i32.a * b->un.i32.a;
|
|
||||||
out->un.i32.b = a->un.i32.b * b->un.i32.b;
|
|
||||||
}
|
|
||||||
static void default_reciprocal_i32(MwLLVec* a, MwLLVec* out) {
|
|
||||||
out->un.i32.a = pow(a->un.i32.a, -1);
|
|
||||||
out->un.i32.b = pow(a->un.i32.b, -1);
|
|
||||||
};
|
|
||||||
static void default_squareRoot_i32(MwLLVec* a, MwLLVec* out) {
|
|
||||||
out->un.i32.a = sqrt(a->un.i32.a);
|
|
||||||
out->un.i32.b = sqrt(a->un.i32.b);
|
|
||||||
};
|
|
||||||
|
|
||||||
static void default_equal_i32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
|
||||||
out->un.i32.a = a->un.i32.a == b->un.i32.a;
|
|
||||||
out->un.i32.b = a->un.i32.b == b->un.i32.b;
|
|
||||||
}
|
|
||||||
static void default_greaterThen_i32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
|
||||||
out->un.i32.a = a->un.i32.a >= b->un.i32.a;
|
|
||||||
out->un.i32.b = a->un.i32.b >= b->un.i32.b;
|
|
||||||
}
|
|
||||||
static MwLLMathVTable table_i32 = {
|
|
||||||
default_add_i32,
|
|
||||||
default_multiply_i32,
|
|
||||||
default_sub_i32,
|
|
||||||
default_reciprocal_i32,
|
|
||||||
default_squareRoot_i32,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
default_shiftRight_u32,
|
|
||||||
default_shiftLeft_u32,
|
|
||||||
default_equal_i32,
|
|
||||||
default_greaterThen_i32,
|
|
||||||
NULL};
|
|
||||||
|
|
||||||
static MwLLMathVTable* defaultMultiTable[_MwLLVecType_Max] = {
|
|
||||||
&table_u8, // _MwLLVecTypeU8x8
|
|
||||||
&table_u16, // _MwLLVecTypeU16x4
|
|
||||||
&table_u32, // _MwLLVecTypeU32x2
|
|
||||||
&table_i8, // _MwLLVecTypeI8x8
|
|
||||||
&table_i16, // _MwLLVecTypeI16x4
|
|
||||||
&table_i32, // _MwLLVecTypeI32x2
|
|
||||||
};
|
|
||||||
|
|
||||||
MwLLMathVTable** default_multi_table(void) {
|
|
||||||
return defaultMultiTable;
|
|
||||||
}
|
}
|
||||||
|
|||||||
214
src/math/math.c
214
src/math/math.c
@@ -3,45 +3,17 @@
|
|||||||
|
|
||||||
#include "math_internal.h"
|
#include "math_internal.h"
|
||||||
|
|
||||||
MwLLVec _MwLLVecCreateGeneric(int ty, ...) {
|
#if defined(MwLLMath_x86)
|
||||||
MwLLVecUnion un;
|
struct x86Features {
|
||||||
MwLLVec vec;
|
MwBool mmx;
|
||||||
va_list va;
|
MwBool sse2;
|
||||||
|
};
|
||||||
|
|
||||||
va_start(va, ty);
|
static struct x86Features
|
||||||
|
getCPUFeatures(void) {
|
||||||
// clang-format off
|
MwU32 _eax = 1;
|
||||||
#define _A_B(ty) un.ty.a = va_arg(va, int); un.ty.b = va_arg(va, int);
|
MwU32 _edx;
|
||||||
#define _C_D(ty) un.ty.c = va_arg(va, int); un.ty.d = va_arg(va, int);
|
struct x86Features features;
|
||||||
#define _E_F(ty) un.ty.e = va_arg(va, int); un.ty.f = va_arg(va, int);
|
|
||||||
#define _G_H(ty) un.ty.g = va_arg(va, int); un.ty.h = va_arg(va, int);
|
|
||||||
switch(ty) {
|
|
||||||
case _MwLLVecTypeU8x8: _A_B(u8); _C_D(u8); _E_F(u8); _G_H(u8); break;
|
|
||||||
case _MwLLVecTypeU16x4: _A_B(u16); _C_D(u16); break;
|
|
||||||
case _MwLLVecTypeU32x2: _A_B(u32); break;
|
|
||||||
case _MwLLVecTypeI8x8: _A_B(i8); _C_D(i8); _E_F(i8); _G_H(i8); break;
|
|
||||||
case _MwLLVecTypeI16x4: _A_B(i16); _C_D(i16); break;
|
|
||||||
case _MwLLVecTypeI32x2: _A_B(i32); break;
|
|
||||||
case _MwLLVecType_Max: break;
|
|
||||||
}
|
|
||||||
#undef _A_B
|
|
||||||
#undef _C_D
|
|
||||||
#undef _E_F
|
|
||||||
#undef _G_H
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
va_end(va);
|
|
||||||
|
|
||||||
vec.ty = ty;
|
|
||||||
vec.un = un;
|
|
||||||
|
|
||||||
return vec;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(MwLLMathMMX)
|
|
||||||
static MwU32 getCPUFeatures(void) {
|
|
||||||
MwU32 _eax = 1;
|
|
||||||
MwU32 _edx;
|
|
||||||
|
|
||||||
#ifdef __WATCOMC__
|
#ifdef __WATCOMC__
|
||||||
__asm {
|
__asm {
|
||||||
@@ -56,87 +28,159 @@ static MwU32 getCPUFeatures(void) {
|
|||||||
: "a"(1) : "ebx", "ecx");
|
: "a"(1) : "ebx", "ecx");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return _edx;
|
if(_edx & FEATX86_MMX) {
|
||||||
|
features.mmx = MwTRUE;
|
||||||
|
}
|
||||||
|
if(_edx & FEATX86_SSE2) {
|
||||||
|
features.sse2 = MwTRUE;
|
||||||
|
}
|
||||||
|
return features;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static MwLLMathVTable** mwLLMultiTable;
|
static int round_multiple(int num, int mul) {
|
||||||
static MwLLMathVTable* multiTableSetupAndGet(int ty);
|
return ((num + mul - 1) / mul) * mul;
|
||||||
static MwLLMathVTable* multiTableGet(int ty);
|
|
||||||
|
|
||||||
static MwLLMathVTable* (*mwLLmathFunc)(int ty) = multiTableSetupAndGet;
|
|
||||||
|
|
||||||
static MwLLMathVTable* getMultiTable(int ty) {
|
|
||||||
return mwLLmathFunc(ty);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static MwLLMathVTable* multiTableSetupAndGet(int ty) {
|
MwLLVec* MwLLVaVecCreate(int ty, MwU64 size, ...) {
|
||||||
#if defined(MwLLMathMMX)
|
struct x86Features features = getCPUFeatures();
|
||||||
MwU32 features;
|
MwLLVec* vec = malloc(sizeof(MwLLVec));
|
||||||
#endif
|
va_list va;
|
||||||
|
int i = 0;
|
||||||
|
int size_rounded = size;
|
||||||
|
|
||||||
mwLLMultiTable = default_multi_table();
|
memset(vec, 0, sizeof(MwLLVec));
|
||||||
|
|
||||||
#if defined(MwLLMathMMX)
|
vec->size = size;
|
||||||
features = getCPUFeatures();
|
|
||||||
printf("Avaliable x86_64 Features:\n");
|
|
||||||
printf("\tMMX: %s\n", features & FEATX86_MMX ? "true" : "false");
|
|
||||||
printf("\tSSE: %s\n", features & FEATX86_SSE ? "true" : "false");
|
|
||||||
printf("\tSSE2: %s\n", features & FEATX86_SSE2 ? "true" : "false");
|
|
||||||
|
|
||||||
if(features & FEATX86_MMX) {
|
#ifdef MwLLMath_x86
|
||||||
mmx_apply(mwLLMultiTable);
|
if(features.mmx) {
|
||||||
|
size_rounded = round_multiple(size, 64);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mwLLmathFunc = multiTableGet;
|
va_start(va, size);
|
||||||
|
|
||||||
return mwLLMultiTable[ty];
|
switch(ty) {
|
||||||
}
|
case MwLLVecTypeU8:
|
||||||
static MwLLMathVTable* multiTableGet(int ty) {
|
case MwLLVecTypeI8:
|
||||||
return mwLLMultiTable[ty];
|
vec->buffer = malloc(size_rounded * sizeof(MwU8));
|
||||||
|
memset(vec->buffer, 0, size_rounded);
|
||||||
|
for(; i < size; i++) {
|
||||||
|
((MwU8*)vec->buffer)[i] = va_arg(va, int);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MwLLVecTypeU16:
|
||||||
|
case MwLLVecTypeI16:
|
||||||
|
vec->buffer = malloc(size_rounded * sizeof(MwU16));
|
||||||
|
memset(vec->buffer, 0, size_rounded);
|
||||||
|
for(; i < size; i++) {
|
||||||
|
((MwU16*)vec->buffer)[i] = va_arg(va, int);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MwLLVecTypeU32:
|
||||||
|
case MwLLVecTypeI32:
|
||||||
|
vec->buffer = malloc(size_rounded * sizeof(MwU32));
|
||||||
|
memset(vec->buffer, 0, size_rounded);
|
||||||
|
for(; i < size; i++) {
|
||||||
|
((MwU32*)vec->buffer)[i] = va_arg(va, int);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MwLLVecTypeU64:
|
||||||
|
case MwLLVecTypeI64:
|
||||||
|
vec->buffer = malloc(size_rounded * sizeof(MwU64));
|
||||||
|
memset(vec->buffer, 0, size_rounded);
|
||||||
|
for(; i < size; i++) {
|
||||||
|
((MwU64*)vec->buffer)[i] = va_arg(va, int);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("Unknown MwLLVecType %d\n", ty);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(va);
|
||||||
|
|
||||||
|
default_apply(vec);
|
||||||
|
|
||||||
|
#ifdef MwLLMath_x86
|
||||||
|
if(features.mmx) {
|
||||||
|
mmx_apply(vec);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Flag for telling debug builds so we can selectively take this out
|
||||||
|
#define dbg_assert(a) assert(a)
|
||||||
|
|
||||||
void MwLLMathAdd(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
void MwLLMathAdd(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty);
|
dbg_assert(a->size == b->size && a->size == out->size && b->size && out->size);
|
||||||
getMultiTable(a->ty)->Add(a, b, out);
|
a->vtable.add(a, b, out);
|
||||||
}
|
}
|
||||||
void MwLLMathSub(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
void MwLLMathSub(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty);
|
dbg_assert(a->size == b->size && a->size == out->size && b->size && out->size);
|
||||||
getMultiTable(a->ty)->Sub(a, b, out);
|
a->vtable.sub(a, b, out);
|
||||||
}
|
}
|
||||||
void MwLLMathMultiply(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
void MwLLMathMultiply(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty);
|
dbg_assert(a->size == b->size && a->size == out->size && b->size && out->size);
|
||||||
getMultiTable(a->ty)->Multiply(a, b, out);
|
a->vtable.multiply(a, b, out);
|
||||||
}
|
}
|
||||||
void MwLLMathReciprocal(MwLLVec* a, MwLLVec* out) {
|
void MwLLMathReciprocal(MwLLVec* a, MwLLVec* out) {
|
||||||
assert(a->ty == out->ty);
|
dbg_assert(a->size == out->size);
|
||||||
getMultiTable(a->ty)->Reciprocal(a, out);
|
a->vtable.reciprocal(a, out);
|
||||||
}
|
}
|
||||||
void MwLLMathSquareRoot(MwLLVec* a, MwLLVec* out) {
|
void MwLLMathSquareRoot(MwLLVec* a, MwLLVec* out) {
|
||||||
assert(a->ty == out->ty);
|
dbg_assert(a->size == out->size);
|
||||||
getMultiTable(a->ty)->SquareRoot(a, out);
|
a->vtable.squareRoot(a, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MwLLMathShiftRight(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
void MwLLMathShiftRight(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty);
|
dbg_assert(a->size == b->size && a->size == out->size && b->size && out->size);
|
||||||
getMultiTable(a->ty)->ShiftRight(a, b, out);
|
a->vtable.shiftRight(a, b, out);
|
||||||
}
|
}
|
||||||
void MwLLMathShiftLeft(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
void MwLLMathShiftLeft(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty);
|
dbg_assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty);
|
||||||
getMultiTable(a->ty)->ShiftLeft(a, b, out);
|
a->vtable.shiftLeft(a, b, out);
|
||||||
}
|
}
|
||||||
void MwLLMathEqual(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
void MwLLMathEqual(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty);
|
dbg_assert(a->size == b->size && a->size == out->size && b->size && out->size);
|
||||||
getMultiTable(a->ty)->Equal(a, b, out);
|
|
||||||
}
|
}
|
||||||
void MwLLMathGreaterThen(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
void MwLLMathGreaterThen(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty);
|
dbg_assert(a->size == b->size && a->size == out->size && b->size && out->size);
|
||||||
getMultiTable(a->ty)->GreaterThen(a, b, out);
|
a->vtable.shiftRight(a, b, out);
|
||||||
}
|
}
|
||||||
void MwLLMathAnd(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
void MwLLMathAnd(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
out->un.all = a->un.all & b->un.all;
|
dbg_assert(a->size == b->size && a->size == out->size && b->size && out->size);
|
||||||
|
a->vtable.and (a, b, out);
|
||||||
}
|
}
|
||||||
void MwLLMathOr(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
void MwLLMathOr(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
out->un.all = a->un.all | b->un.all;
|
dbg_assert(a->size == b->size && a->size == out->size && b->size && out->size);
|
||||||
|
a->vtable.or (a, b, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MWDECL MwU8 MwLLVecIndexU8(MwLLVec* vec, MwU64 index) {
|
||||||
|
return ((MwU8*)vec->buffer)[index];
|
||||||
|
};
|
||||||
|
MWDECL MwU16 MwLLVecIndexU16(MwLLVec* vec, MwU64 index) {
|
||||||
|
return ((MwU16*)vec->buffer)[index];
|
||||||
|
};
|
||||||
|
MWDECL MwU32 MwLLVecIndexU32(MwLLVec* vec, MwU64 index) {
|
||||||
|
return ((MwU32*)vec->buffer)[index];
|
||||||
|
};
|
||||||
|
MWDECL MwU64 MwLLVecIndexU64(MwLLVec* vec, MwU64 index) {
|
||||||
|
return ((MwU64*)vec->buffer)[index];
|
||||||
|
};
|
||||||
|
MWDECL MwI8 MwLLVecIndexI8(MwLLVec* vec, MwU64 index) {
|
||||||
|
return ((MwI8*)vec->buffer)[index];
|
||||||
|
};
|
||||||
|
MWDECL MwI16 MwLLVecIndexI16(MwLLVec* vec, MwU64 index) {
|
||||||
|
return ((MwI16*)vec->buffer)[index];
|
||||||
|
};
|
||||||
|
MWDECL MwI32 MwLLVecIndexI32(MwLLVec* vec, MwU64 index) {
|
||||||
|
return ((MwI32*)vec->buffer)[index];
|
||||||
|
};
|
||||||
|
MWDECL MwI64 MwLLVecIndexI64(MwLLVec* vec, MwU64 index) {
|
||||||
|
return ((MwI64*)vec->buffer)[index];
|
||||||
|
};
|
||||||
|
|||||||
@@ -6,31 +6,38 @@
|
|||||||
#include <Mw/BaseTypes.h>
|
#include <Mw/BaseTypes.h>
|
||||||
#include <Mw/LowLevelMath.h>
|
#include <Mw/LowLevelMath.h>
|
||||||
|
|
||||||
/* Bitfield of cpu features we get from x86's CPUID */
|
|
||||||
#if defined(MwLLMathMMX)
|
|
||||||
#define FEATX86_MMX (1 << 23)
|
|
||||||
#define FEATX86_SSE (1 << 25)
|
|
||||||
#define FEATX86_SSE2 (1 << 26)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct _MwLLMathVTable {
|
|
||||||
void (*Add)(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
|
||||||
void (*Multiply)(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
|
||||||
void (*Sub)(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
|
||||||
void (*Reciprocal)(MwLLVec* a, MwLLVec* out);
|
|
||||||
void (*SquareRoot)(MwLLVec* a, MwLLVec* out);
|
|
||||||
void (*And)(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
|
||||||
void (*Or)(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
|
||||||
void (*ShiftRight)(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
|
||||||
void (*ShiftLeft)(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
|
||||||
void (*Equal)(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
|
||||||
void (*GreaterThen)(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
|
||||||
void (*LesserThen)(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct _MwLLMathVTable MwLLMathVTable;
|
typedef struct _MwLLMathVTable MwLLMathVTable;
|
||||||
|
|
||||||
MwLLMathVTable** default_multi_table(void);
|
struct _MwLLMathVTable {
|
||||||
void mmx_apply(MwLLMathVTable**);
|
void (*add)(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||||
|
void (*multiply)(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||||
|
void (*sub)(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||||
|
void (*reciprocal)(MwLLVec* a, MwLLVec* out);
|
||||||
|
void (*squareRoot)(MwLLVec* a, MwLLVec* out);
|
||||||
|
void (*and)(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||||
|
void (*or)(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||||
|
void (*shiftRight)(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||||
|
void (*shiftLeft)(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||||
|
void (*equal)(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||||
|
void (*greaterThen)(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||||
|
void (*lesserThen)(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _MwLLVec {
|
||||||
|
void* buffer;
|
||||||
|
int ty;
|
||||||
|
MwU64 size;
|
||||||
|
MwLLMathVTable vtable;
|
||||||
|
};
|
||||||
|
|
||||||
|
void default_apply(MwLLVec*);
|
||||||
|
|
||||||
|
/* Bitfield of cpu features we get from x86's CPUID */
|
||||||
|
#if defined(MwLLMath_x86)
|
||||||
|
#define FEATX86_MMX (1 << 23)
|
||||||
|
// #define FEATX86_SSE (1 << 25)
|
||||||
|
#define FEATX86_SSE2 (1 << 26)
|
||||||
|
void mmx_apply(MwLLVec*);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
136
src/math/mmx.c
136
src/math/mmx.c
@@ -1,111 +1,129 @@
|
|||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
#include <Mw/LowLevelMath.h>
|
#include <Mw/LowLevelMath.h>
|
||||||
|
|
||||||
#ifdef MwLLMathMMX
|
#ifdef MwLLMath_x86
|
||||||
#include "math_internal.h"
|
#include "math_internal.h"
|
||||||
#include <mmintrin.h>
|
#include <mmintrin.h>
|
||||||
|
|
||||||
#define DO_MMX_INTRINSIC(intrin, _ty, _rty, _tyn) \
|
#define DO_MMX_INTRINSIC(intrin, _ty, _cty) \
|
||||||
__m64 m = intrin(*(__m64*)&a->un._ty, *(__m64*)&b->un._ty); \
|
int i = 0; \
|
||||||
struct _tyn* t = (struct _tyn*)&m; \
|
for(; i < a->size; i += 8) { \
|
||||||
out->un._rty = *t;
|
__m64 m = intrin(*(__m64*)&a->buffer[i], *(__m64*)&b->buffer[i]); \
|
||||||
|
memcpy(&((_cty*)out->buffer)[i], &m, sizeof(m)); \
|
||||||
|
}
|
||||||
|
|
||||||
static void mmx_add8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
static void mmx_add8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
DO_MMX_INTRINSIC(_m_paddb, u8, u8, _MwLLVecDataU8x8);
|
DO_MMX_INTRINSIC(_m_paddb, u8, MwU8)
|
||||||
}
|
}
|
||||||
static void mmx_sub8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
static void mmx_sub8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
DO_MMX_INTRINSIC(_m_psubb, u8, u8, _MwLLVecDataU8x8);
|
DO_MMX_INTRINSIC(_m_psubb, u8, MwU8);
|
||||||
}
|
}
|
||||||
static void mmx_equal8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
static void mmx_equal8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
DO_MMX_INTRINSIC(_m_pcmpeqb, u8, u8, _MwLLVecDataU8x8);
|
DO_MMX_INTRINSIC(_m_pcmpeqb, u8, MwU8);
|
||||||
}
|
}
|
||||||
static void mmx_add16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
static void mmx_add16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
DO_MMX_INTRINSIC(_m_paddw, u16, u16, _MwLLVecDataU16x4);
|
DO_MMX_INTRINSIC(_m_paddw, u16, MwU16);
|
||||||
}
|
}
|
||||||
static void mmx_sub16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
static void mmx_sub16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
DO_MMX_INTRINSIC(_m_psubw, u16, u16, _MwLLVecDataU16x4);
|
DO_MMX_INTRINSIC(_m_psubw, u16, MwU16);
|
||||||
}
|
}
|
||||||
static void mmx_shiftRight16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
static void mmx_shiftRight16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
DO_MMX_INTRINSIC(_m_psrlw, u16, u16, _MwLLVecDataU16x4);
|
DO_MMX_INTRINSIC(_m_psrlw, u16, MwU16);
|
||||||
}
|
}
|
||||||
static void mmx_shiftLeft16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
static void mmx_shiftLeft16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
DO_MMX_INTRINSIC(_m_psllw, u16, u16, _MwLLVecDataU16x4);
|
DO_MMX_INTRINSIC(_m_psllw, u16, MwU16);
|
||||||
}
|
}
|
||||||
static void mmx_equal16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
static void mmx_equal16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
DO_MMX_INTRINSIC(_m_pcmpeqw, u16, u16, _MwLLVecDataU16x4);
|
DO_MMX_INTRINSIC(_m_pcmpeqw, u16, MwU16);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mmx_add32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
static void mmx_add32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
DO_MMX_INTRINSIC(_m_paddd, u32, u32, _MwLLVecDataU32x2);
|
DO_MMX_INTRINSIC(_m_paddd, u32, MwU32);
|
||||||
}
|
}
|
||||||
static void mmx_sub32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
static void mmx_sub32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
DO_MMX_INTRINSIC(_m_psubd, u32, u32, _MwLLVecDataU32x2);
|
DO_MMX_INTRINSIC(_m_psubd, u32, MwU32);
|
||||||
}
|
}
|
||||||
static void mmx_shiftRight32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
static void mmx_shiftRight32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
DO_MMX_INTRINSIC(_m_psrld, u32, u32, _MwLLVecDataU32x2);
|
DO_MMX_INTRINSIC(_m_psrld, u32, MwU32);
|
||||||
}
|
}
|
||||||
static void mmx_shiftLeft32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
static void mmx_shiftLeft32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
DO_MMX_INTRINSIC(_m_pslld, u32, u32, _MwLLVecDataU32x2);
|
DO_MMX_INTRINSIC(_m_pslld, u32, MwU32);
|
||||||
}
|
}
|
||||||
static void mmx_equal32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
static void mmx_equal32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
DO_MMX_INTRINSIC(_m_pcmpeqw, u32, u32, _MwLLVecDataU32x2);
|
DO_MMX_INTRINSIC(_m_pcmpeqw, u32, MwU32);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mmx_addi8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
static void mmx_addi8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
DO_MMX_INTRINSIC(_m_paddsb, u8, u8, _MwLLVecDataU8x8);
|
DO_MMX_INTRINSIC(_m_paddsb, i8, MwI8);
|
||||||
}
|
}
|
||||||
static void mmx_subi8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
static void mmx_subi8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
DO_MMX_INTRINSIC(_m_psubsb, u8, u8, _MwLLVecDataU8x8);
|
DO_MMX_INTRINSIC(_m_psubsb, i8, MwI8);
|
||||||
}
|
}
|
||||||
static void mmx_addi16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
static void mmx_addi16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
DO_MMX_INTRINSIC(_m_paddsw, u16, u16, _MwLLVecDataU16x4);
|
DO_MMX_INTRINSIC(_m_paddsw, i16, MwI16);
|
||||||
}
|
}
|
||||||
static void mmx_subi16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
static void mmx_subi16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
DO_MMX_INTRINSIC(_m_psubsw, u16, u16, _MwLLVecDataU16x4);
|
DO_MMX_INTRINSIC(_m_psubsw, i16, MwI16);
|
||||||
}
|
}
|
||||||
static void mmx_greaterTheni8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
static void mmx_greaterTheni8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
DO_MMX_INTRINSIC(_m_pcmpgtb, u8, u8, _MwLLVecDataU8x8);
|
DO_MMX_INTRINSIC(_m_pcmpgtb, i8, MwI8);
|
||||||
}
|
}
|
||||||
static void mmx_greaterTheni16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
static void mmx_greaterTheni16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
DO_MMX_INTRINSIC(_m_pcmpgtw, u16, u16, _MwLLVecDataU16x4);
|
DO_MMX_INTRINSIC(_m_pcmpgtw, i16, MwI16);
|
||||||
}
|
}
|
||||||
static void mmx_greaterTheni32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
static void mmx_greaterTheni32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||||
DO_MMX_INTRINSIC(_m_pcmpgtd, u32, u32, _MwLLVecDataU32x2);
|
DO_MMX_INTRINSIC(_m_pcmpgtd, i32, MwI16);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mmx_apply(MwLLMathVTable** t) {
|
void mmx_apply(MwLLVec* vec) {
|
||||||
t[_MwLLVecTypeU8x8]->Add = mmx_add8;
|
switch(vec->ty) {
|
||||||
t[_MwLLVecTypeU8x8]->Sub = mmx_sub8;
|
case MwLLVecTypeU8:
|
||||||
// t[_MwLLVecTypeU8x8]->GreaterThen = mmx_greaterThen8;
|
vec->vtable.add = mmx_add8;
|
||||||
t[_MwLLVecTypeU8x8]->Equal = mmx_equal8;
|
vec->vtable.sub = mmx_sub8;
|
||||||
t[_MwLLVecTypeU16x4]->Add = mmx_add16;
|
vec->vtable.equal = mmx_equal8;
|
||||||
t[_MwLLVecTypeU16x4]->Sub = mmx_sub16;
|
break;
|
||||||
t[_MwLLVecTypeU16x4]->ShiftLeft = mmx_shiftLeft16;
|
case MwLLVecTypeU16:
|
||||||
t[_MwLLVecTypeU16x4]->ShiftRight = mmx_shiftRight16;
|
vec->vtable.add = mmx_add16;
|
||||||
// t[_MwLLVecTypeU16x4]->GreaterThen = mmx_greaterThen16;
|
vec->vtable.sub = mmx_sub16;
|
||||||
t[_MwLLVecTypeU16x4]->Equal = mmx_equal16;
|
vec->vtable.shiftLeft = mmx_shiftLeft16;
|
||||||
t[_MwLLVecTypeU32x2]->Add = mmx_add32;
|
vec->vtable.shiftRight = mmx_shiftRight16;
|
||||||
t[_MwLLVecTypeU32x2]->Sub = mmx_sub32;
|
vec->vtable.equal = mmx_equal16;
|
||||||
t[_MwLLVecTypeU32x2]->ShiftLeft = mmx_shiftLeft32;
|
break;
|
||||||
t[_MwLLVecTypeU32x2]->ShiftRight = mmx_shiftRight32;
|
case MwLLVecTypeU32:
|
||||||
// t[_MwLLVecTypeU32x2]->GreaterThen = mmx_greaterThen32;
|
vec->vtable.add = mmx_add32;
|
||||||
t[_MwLLVecTypeU32x2]->Equal = mmx_equal32;
|
vec->vtable.sub = mmx_sub32;
|
||||||
|
vec->vtable.shiftLeft = mmx_shiftLeft32;
|
||||||
t[_MwLLVecTypeU8x8]->Add = mmx_addi8;
|
vec->vtable.shiftRight = mmx_shiftRight32;
|
||||||
t[_MwLLVecTypeU8x8]->Sub = mmx_subi8;
|
vec->vtable.equal = mmx_equal32;
|
||||||
t[_MwLLVecTypeI8x8]->GreaterThen = mmx_greaterTheni8;
|
break;
|
||||||
t[_MwLLVecTypeI8x8]->Equal = mmx_equal8;
|
case MwLLVecTypeU64:
|
||||||
t[_MwLLVecTypeU16x4]->Add = mmx_addi16;
|
break;
|
||||||
t[_MwLLVecTypeU16x4]->Sub = mmx_subi16;
|
case MwLLVecTypeI8:
|
||||||
t[_MwLLVecTypeI16x4]->ShiftLeft = mmx_shiftLeft16;
|
vec->vtable.add = mmx_addi8;
|
||||||
t[_MwLLVecTypeI16x4]->ShiftRight = mmx_shiftRight16;
|
vec->vtable.sub = mmx_subi8;
|
||||||
t[_MwLLVecTypeI16x4]->GreaterThen = mmx_greaterTheni16;
|
vec->vtable.greaterThen = mmx_greaterTheni8;
|
||||||
t[_MwLLVecTypeI16x4]->Equal = mmx_equal16;
|
vec->vtable.equal = mmx_equal8;
|
||||||
t[_MwLLVecTypeI32x2]->Add = mmx_add32;
|
break;
|
||||||
t[_MwLLVecTypeI32x2]->Sub = mmx_sub32;
|
case MwLLVecTypeI16:
|
||||||
t[_MwLLVecTypeI32x2]->ShiftLeft = mmx_shiftLeft32;
|
vec->vtable.add = mmx_addi16;
|
||||||
t[_MwLLVecTypeI32x2]->ShiftRight = mmx_shiftRight32;
|
vec->vtable.sub = mmx_subi16;
|
||||||
t[_MwLLVecTypeI32x2]->GreaterThen = mmx_greaterTheni32;
|
vec->vtable.shiftLeft = mmx_shiftLeft16;
|
||||||
t[_MwLLVecTypeI32x2]->Equal = mmx_equal32;
|
vec->vtable.shiftRight = mmx_shiftRight16;
|
||||||
|
vec->vtable.greaterThen = mmx_greaterTheni16;
|
||||||
|
vec->vtable.equal = mmx_equal16;
|
||||||
|
break;
|
||||||
|
case MwLLVecTypeI32:
|
||||||
|
vec->vtable.add = mmx_add32;
|
||||||
|
vec->vtable.sub = mmx_sub32;
|
||||||
|
vec->vtable.shiftLeft = mmx_shiftLeft32;
|
||||||
|
vec->vtable.shiftRight = mmx_shiftRight32;
|
||||||
|
vec->vtable.greaterThen = mmx_greaterTheni32;
|
||||||
|
vec->vtable.equal = mmx_equal32;
|
||||||
|
break;
|
||||||
|
case MwLLVecTypeI64:
|
||||||
|
break;
|
||||||
|
case MwLLVecType_Max:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user