mirror of
https://gitea.nishi.boats/pyrite-dev/milsko
synced 2025-12-31 06:30:52 +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>
|
||||
|
||||
int main() {
|
||||
MwWidget w = MwVaCreateWidget(MwWindowClass, "main", NULL, MwDEFAULT,
|
||||
MwDEFAULT, 640, 480, MwNtitle, "test", NULL);
|
||||
MwWidget cpicker;
|
||||
MwWidget window;
|
||||
MwWidget button;
|
||||
|
||||
MwWidget cpicker = MwColorPicker(w, "cpicker");
|
||||
void color_callback(MwRGB rgb) {
|
||||
char hexColor[8];
|
||||
|
||||
(void)cpicker;
|
||||
|
||||
MwLoop(w);
|
||||
sprintf(hexColor, "#%02X%02X%02X", rgb.r, rgb.g, rgb.b);
|
||||
MwSetText(window, MwNbackground, hexColor);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
typedef struct _MwRGB MwRGB;
|
||||
typedef struct _MwHSV MwHSV;
|
||||
|
||||
struct _MwRGB {
|
||||
double r;
|
||||
double g;
|
||||
double b;
|
||||
MwU32 r;
|
||||
MwU32 g;
|
||||
MwU32 b;
|
||||
};
|
||||
|
||||
struct _MwHSV {
|
||||
double h; // angle in degrees
|
||||
double s; // a fraction between 0 and 1
|
||||
double v; // a fraction between 0 and 1
|
||||
};
|
||||
typedef void (*MwColorPickerCallback)(MwRGB rgb);
|
||||
|
||||
MWDECL MwWidget MwColorPicker(MwWidget handle, const char* title);
|
||||
MWDECL MwWidget MwColorPicker(MwWidget handle, const char* title, MwColorPickerCallback cb);
|
||||
|
||||
#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);
|
||||
|
||||
/*!
|
||||
* @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
|
||||
* @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 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 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 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 MwLLDrawPixmap(MwLL handle, MwRect* rect, MwLLPixmap pixmap);
|
||||
MWDECL void MwLLSetIcon(MwLL handle, MwLLPixmap pixmap);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* $Id$ */
|
||||
/*!
|
||||
* @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.
|
||||
*/
|
||||
|
||||
@@ -12,70 +12,123 @@
|
||||
#include <Mw/MachDep.h>
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__) || defined(__WATCOMC__)
|
||||
#define MwLLMathMMX
|
||||
#endif
|
||||
|
||||
#if !defined(MwLLMathMMX)
|
||||
// #warning LowLevelMath.h does not yet support this platform
|
||||
#define MwLLMath_x86
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @brief Generic vector type
|
||||
* @warning Do not try to instantiate this yourself, use the appropriate functions instead.
|
||||
* @brief SIMD vector
|
||||
*/
|
||||
|
||||
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
|
||||
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;
|
||||
MwLLVecType_Max,
|
||||
};
|
||||
|
||||
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)
|
||||
#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)
|
||||
#define MwLLVecI16x4(a, b, c, d) _MwLLVecCreateGeneric(_MwLLVecTypeI16x4, a, b, c, d)
|
||||
#define MwLLVecI32x2(a, b) _MwLLVecCreateGeneric(_MwLLVecTypeI32x2, a, b)
|
||||
/*!
|
||||
* @brief Destroy the given SIMD Vector
|
||||
*/
|
||||
MWDECL void MwLLVecDestroy(MwLLVec* vec);
|
||||
|
||||
/*!
|
||||
* @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);
|
||||
/*!
|
||||
* @brief SIMD Vector multiply
|
||||
*/
|
||||
MWDECL void MwLLMathMultiply(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||
/*!
|
||||
* @brief SIMD Vector subtract
|
||||
*/
|
||||
MWDECL void MwLLMathSub(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||
/*!
|
||||
* @brief SIMD Vector reciprocal
|
||||
*/
|
||||
MWDECL void MwLLMathReciprocal(MwLLVec* a, MwLLVec* out);
|
||||
/*!
|
||||
* @brief SIMD Vector square root
|
||||
*/
|
||||
MWDECL void MwLLMathSquareRoot(MwLLVec* a, MwLLVec* out);
|
||||
/*!
|
||||
* @brief SIMD Vector bitwise and
|
||||
*/
|
||||
MWDECL void MwLLMathAnd(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||
/*!
|
||||
* @brief SIMD Vector bitwise or
|
||||
*/
|
||||
MWDECL void MwLLMathOr(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||
/*!
|
||||
* @brief SIMD Vector bitwise shift right
|
||||
*/
|
||||
MWDECL void MwLLMathShiftRight(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||
/*!
|
||||
* @brief SIMD Vector bitwise shift left
|
||||
*/
|
||||
MWDECL void MwLLMathShiftLeft(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||
/*!
|
||||
* @brief SIMD Vector bitwise equal
|
||||
*/
|
||||
MWDECL void MwLLMathEqual(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||
/*!
|
||||
* @brief SIMD Vector greater then
|
||||
*/
|
||||
MWDECL void MwLLMathGreaterThen(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||
/*!
|
||||
* @brief SIMD Vector lesser then
|
||||
*/
|
||||
MWDECL void MwLLMathLesserThen(MwLLVec* a, MwLLVec* b, MwLLVec* out);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -43,8 +43,9 @@ struct _MwLLColor {
|
||||
};
|
||||
|
||||
struct _MwLLPixmap {
|
||||
int width;
|
||||
int height;
|
||||
int width;
|
||||
int height;
|
||||
unsigned char* data_scratch_buf;
|
||||
|
||||
HBITMAP hBitmap;
|
||||
HBITMAP hMask;
|
||||
|
||||
@@ -233,6 +233,30 @@ MwLLColor MwLLAllocColor(MwLL handle, int r, int g, int b) {
|
||||
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) {
|
||||
Window root;
|
||||
unsigned int border, depth;
|
||||
@@ -435,6 +459,9 @@ MwLLPixmap MwLLCreatePixmap(MwLL handle, unsigned char* data, int width, int hei
|
||||
int evbase, erbase;
|
||||
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);
|
||||
|
||||
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->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++) {
|
||||
for(x = 0; x < width; x++) {
|
||||
unsigned char* px = &data[(y * width + x) * 4];
|
||||
MwLLColor c = MwLLAllocColor(handle, px[0], px[1], px[2]);
|
||||
unsigned long p = c->pixel;
|
||||
MwLLPixmapUpdate(handle, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
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);
|
||||
*(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++) {
|
||||
for(x = 0; x < width; x++) {
|
||||
if(data[(y * width + x) * 4 + 3]) {
|
||||
MwLLFreeColor(c);
|
||||
|
||||
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);
|
||||
} else {
|
||||
XPutPixel(r->mask, x, y, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void MwLLDestroyPixmap(MwLLPixmap pixmap) {
|
||||
|
||||
@@ -55,6 +55,7 @@ struct _MwLLPixmap {
|
||||
int width;
|
||||
int height;
|
||||
unsigned char* data;
|
||||
unsigned char* data_buf;
|
||||
|
||||
int depth;
|
||||
|
||||
|
||||
@@ -4,126 +4,155 @@
|
||||
#include "color_picker.h"
|
||||
#include <Mw/LowLevelMath.h>
|
||||
|
||||
static MwRGB hsv2rgb(MwHSV in) {
|
||||
MwRGB out;
|
||||
static void hsv2rgb(MwU32 h, MwU32 s, MwU32 v, MwU32* r, MwU32* g, MwU32* b) {
|
||||
uint8_t sextant = h >> 8;
|
||||
|
||||
int i = (int)(floor(in.h * 6));
|
||||
double f = in.h * 6 - i;
|
||||
double p = in.v * (1 - in.s);
|
||||
double q = in.v * (1 - f * in.s);
|
||||
double t = in.v * (1 - (1 - f) * in.s);
|
||||
#define HSV_SWAPPTR(a, b) \
|
||||
do { \
|
||||
MwU32* tmp = a; \
|
||||
a = b; \
|
||||
b = tmp; \
|
||||
} while(0)
|
||||
|
||||
switch(i % 6) {
|
||||
case 0:
|
||||
out.r = in.v, out.g = t, out.b = p;
|
||||
break;
|
||||
case 1:
|
||||
out.r = q, out.g = in.v, out.b = p;
|
||||
break;
|
||||
case 2:
|
||||
out.r = p, out.g = in.v, out.b = t;
|
||||
break;
|
||||
case 3:
|
||||
out.r = p, out.g = q, out.b = in.v;
|
||||
break;
|
||||
case 4:
|
||||
out.r = t, out.g = p, out.b = in.v;
|
||||
break;
|
||||
case 5:
|
||||
out.r = in.v, out.g = p, out.b = q;
|
||||
break;
|
||||
if(sextant & 2) {
|
||||
HSV_SWAPPTR(r, b);
|
||||
}
|
||||
if(sextant & 4) {
|
||||
|
||||
HSV_SWAPPTR(g, b);
|
||||
}
|
||||
if(!(sextant & 6)) {
|
||||
if(!(sextant & 1)) {
|
||||
HSV_SWAPPTR(r, g);
|
||||
}
|
||||
} else {
|
||||
if(sextant & 1) {
|
||||
HSV_SWAPPTR(r, g);
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
int y, x;
|
||||
static void color_picker_image_update(color_picker* picker) {
|
||||
int y, x;
|
||||
double h;
|
||||
for(y = 0; y < PICKER_SIZE; y++) {
|
||||
for(x = 0; x < PICKER_SIZE; x++) {
|
||||
int i = ((y * PICKER_SIZE) + x) * 4;
|
||||
int _x = x - (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.) {
|
||||
picker->inner.color_picker_image_data[i] = 0;
|
||||
picker->inner.color_picker_image_data[i + 1] = 0;
|
||||
picker->inner.color_picker_image_data[i + 2] = 0;
|
||||
picker->inner.color_picker_image_data[i + 3] = 0;
|
||||
picker->color_picker_image_data[i] = 0;
|
||||
picker->color_picker_image_data[i + 1] = 0;
|
||||
picker->color_picker_image_data[i + 2] = 0;
|
||||
picker->color_picker_image_data[i + 3] = 0;
|
||||
} 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;
|
||||
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) {
|
||||
hue += 360;
|
||||
float angle = atan2(yd, xd) - M_PI;
|
||||
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;
|
||||
picker->inner.color_picker_image_data[i + 1] = color.g * 255;
|
||||
picker->inner.color_picker_image_data[i + 2] = color.b * 255;
|
||||
hsv_v = picker->hue_table[y][x];
|
||||
hsv_v.v = HSV_VAL_MAX - (picker->value * HSV_VAL_MAX);
|
||||
|
||||
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) {
|
||||
MwLLDestroyPixmap(picker->inner.color_picker_pixmap);
|
||||
if(picker->color_picker_pixmap == NULL) {
|
||||
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(
|
||||
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);
|
||||
MwVaApply(picker->color_picker_img, MwNpixmap, picker->color_picker_pixmap, NULL);
|
||||
}
|
||||
|
||||
static void color_picker_click(MwWidget handle, void* user, void* call) {
|
||||
color_picker* picker = (color_picker*)user;
|
||||
MwLLMouse* mouse = (MwLLMouse*)call;
|
||||
char* hexColor;
|
||||
int i, r, g, b, a;
|
||||
char* fgColor;
|
||||
char hexColor[8];
|
||||
int i;
|
||||
char fgColor[8];
|
||||
int fr, fg, fb;
|
||||
|
||||
(void)handle;
|
||||
(void)user;
|
||||
(void)call;
|
||||
|
||||
color_picker_wheel_image_update(picker);
|
||||
color_picker_image_update(picker);
|
||||
|
||||
i = ((mouse->point.y * PICKER_SIZE) + mouse->point.x) * 4;
|
||||
|
||||
r = picker->inner.color_picker_image_data[i];
|
||||
g = picker->inner.color_picker_image_data[i + 1];
|
||||
b = picker->inner.color_picker_image_data[i + 2];
|
||||
a = picker->inner.color_picker_image_data[i + 3];
|
||||
picker->chosen_color.r = picker->color_picker_image_data[i];
|
||||
picker->chosen_color.g = picker->color_picker_image_data[i + 1];
|
||||
picker->chosen_color.b = picker->color_picker_image_data[i + 2];
|
||||
|
||||
(void)a;
|
||||
sprintf(hexColor, "#%02X%02X%02X", picker->chosen_color.r, picker->chosen_color.g, picker->chosen_color.b);
|
||||
|
||||
hexColor = malloc(8);
|
||||
fgColor = malloc(8);
|
||||
sprintf(hexColor, "#%02X%02X%02X", r, g, b);
|
||||
|
||||
fr = r > 128 ? 0 : 255;
|
||||
fg = g > 128 ? 0 : 255;
|
||||
fb = b > 128 ? 0 : 255;
|
||||
fr = picker->chosen_color.r > 128 ? 0 : 255;
|
||||
fg = picker->chosen_color.g > 128 ? 0 : 255;
|
||||
fb = picker->chosen_color.b > 128 ? 0 : 255;
|
||||
|
||||
sprintf(fgColor, "#%02X%02X%02X", fr, fg, fb);
|
||||
MwSetText(picker->inner.color_display, MwNbackground, hexColor);
|
||||
MwSetText(picker->inner.color_display_text, MwNforeground, fgColor);
|
||||
MwSetText(picker->color_display, MwNbackground, hexColor);
|
||||
MwSetText(picker->color_display_text, MwNforeground, fgColor);
|
||||
|
||||
MwSetText(picker->inner.color_display_text, MwNbackground, hexColor);
|
||||
MwSetText(picker->inner.color_display_text, MwNtext, hexColor);
|
||||
free(hexColor);
|
||||
MwSetText(picker->color_display_text, MwNbackground, hexColor);
|
||||
MwSetText(picker->color_display_text, MwNtext, hexColor);
|
||||
}
|
||||
static void color_picker_on_change_value(MwWidget handle, void* user,
|
||||
void* call) {
|
||||
@@ -135,48 +164,75 @@ static void color_picker_on_change_value(MwWidget handle, void* user,
|
||||
(void)diff;
|
||||
(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* picker = malloc(sizeof(color_picker));
|
||||
memset(picker, 0, sizeof(color_picker));
|
||||
|
||||
picker->inner.parent = parent;
|
||||
picker->parent = parent;
|
||||
|
||||
picker->inner.color_picker_img =
|
||||
MwVaCreateWidget(MwImageClass, "image", picker->inner.parent, IMG_POS_X(w), IMG_POS_Y(h),
|
||||
picker->color_picker_img =
|
||||
MwVaCreateWidget(MwImageClass, "image", picker->parent, IMG_POS_X(w), IMG_POS_Y(h),
|
||||
PICKER_SIZE, PICKER_SIZE, NULL);
|
||||
|
||||
picker->inner.color_picker_image_data = malloc(PICKER_SIZE * PICKER_SIZE * 4);
|
||||
picker->inner.color_display_image_data =
|
||||
malloc(PICKER_SIZE * COLOR_DISPLAY_HEIGHT * 4);
|
||||
picker->color_picker_image_data = malloc(PICKER_SIZE * PICKER_SIZE * 4);
|
||||
|
||||
picker->inner.color_picker_pixmap = NULL;
|
||||
picker->inner.color_display_pixmap = NULL;
|
||||
picker->inner.value = 1;
|
||||
picker->color_picker_pixmap = NULL;
|
||||
picker->value = 0;
|
||||
|
||||
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);
|
||||
|
||||
picker->inner.color_display = MwCreateWidget(
|
||||
MwFrameClass, "colorDisplayFrame", picker->inner.parent, IMG_POS_X(w),
|
||||
IMG_POS_Y(h) + PICKER_SIZE + MARGIN, PICKER_SIZE, PICKER_SIZE / 16);
|
||||
MwSetText(picker->inner.color_display, MwNbackground, "#000000");
|
||||
MwSetInteger(picker->inner.color_display, MwnhasBorder, 1);
|
||||
MwSetInteger(picker->inner.color_display, MwNinverted, 1);
|
||||
picker->color_display = MwCreateWidget(
|
||||
MwFrameClass, "colorDisplayFrame", picker->parent, IMG_POS_X(w),
|
||||
IMG_POS_Y(h) - (PICKER_SIZE / 16) - MARGIN, PICKER_SIZE, PICKER_SIZE / 16);
|
||||
MwSetText(picker->color_display, MwNbackground, "#FFFFFF");
|
||||
MwSetInteger(picker->color_display, MwnhasBorder, 1);
|
||||
MwSetInteger(picker->color_display, MwNinverted, 1);
|
||||
|
||||
picker->inner.color_display_text = MwCreateWidget(
|
||||
MwLabelClass, "colorDisplayFrameText", picker->inner.color_display,
|
||||
picker->color_display_text = MwCreateWidget(
|
||||
MwLabelClass, "colorDisplayFrameText", picker->color_display,
|
||||
MwDefaultBorderWidth(parent), MwDefaultBorderWidth(parent),
|
||||
PICKER_SIZE - MwDefaultBorderWidth(parent),
|
||||
(PICKER_SIZE / 16) - (MwDefaultBorderWidth(parent) * 2));
|
||||
|
||||
picker->inner.value_slider = MwVaCreateWidget(
|
||||
MwScrollBarClass, "value-slider", picker->inner.parent,
|
||||
MwSetText(picker->color_display_text, MwNtext, "#FFFFFF");
|
||||
|
||||
picker->value_slider = MwVaCreateWidget(
|
||||
MwScrollBarClass, "value-slider", picker->parent,
|
||||
// x
|
||||
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);
|
||||
|
||||
MwAddUserHandler(picker->inner.value_slider, MwNchangedHandler,
|
||||
MwAddUserHandler(picker->value_slider, MwNchangedHandler,
|
||||
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;
|
||||
};
|
||||
|
||||
MwWidget MwColorPicker(MwWidget handle, const char* title) {
|
||||
MwWidget MwColorPicker(MwWidget handle, const char* title, MwColorPickerCallback cb) {
|
||||
MwPoint p;
|
||||
color_picker* wheel;
|
||||
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;
|
||||
|
||||
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);
|
||||
MwLLMakePopup(window->lowlevel, handle->lowlevel);
|
||||
|
||||
wheel->cb = cb;
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <Mw/ColorPicker.h>
|
||||
#include <Mw/Milsko.h>
|
||||
|
||||
#define WIN_SIZE 512
|
||||
#define PICKER_SIZE 360
|
||||
#define IMG_POS_X(w) ((w - PICKER_SIZE) / 2)
|
||||
#define IMG_POS_Y(h) ((h - PICKER_SIZE) / 2)
|
||||
@@ -13,31 +14,42 @@
|
||||
#define MARGIN (PICKER_SIZE / 32)
|
||||
#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_inner color_picker_inner;
|
||||
typedef struct _color_picker_vtable color_picker_vtable;
|
||||
typedef struct _MwHSV MwHSV;
|
||||
|
||||
struct _color_picker_inner {
|
||||
MwWidget parent;
|
||||
MwWidget color_picker_img;
|
||||
MwWidget value_slider;
|
||||
MwWidget color_display;
|
||||
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 _MwHSV {
|
||||
double h; // angle in degrees
|
||||
double s; // a fraction between 0 and 1
|
||||
double v; // a fraction between 0 and 1
|
||||
MwBool generated;
|
||||
};
|
||||
|
||||
struct _color_picker {
|
||||
color_picker_inner inner;
|
||||
color_picker_vtable vtable;
|
||||
MwWidget parent;
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
*red = color->red;
|
||||
*green = color->green;
|
||||
|
||||
@@ -1,424 +1,110 @@
|
||||
/* $Id$ */
|
||||
#include <Mw/LowLevelMath.h>
|
||||
|
||||
#include "math_internal.h"
|
||||
|
||||
static void default_add_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_sub_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_multiply_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_reciprocal_u8(MwLLVec* a, MwLLVec* out) {
|
||||
out->un.u8.a = pow(a->un.u8.a, -1);
|
||||
out->un.u8.b = pow(a->un.u8.b, -1);
|
||||
out->un.u8.c = pow(a->un.u8.c, -1);
|
||||
out->un.u8.d = pow(a->un.u8.d, -1);
|
||||
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);
|
||||
out->un.u8.h = pow(a->un.u8.h, -1);
|
||||
};
|
||||
static void default_squareRoot_u8(MwLLVec* a, MwLLVec* out) {
|
||||
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);
|
||||
out->un.u8.d = sqrt(a->un.u8.d);
|
||||
out->un.u8.e = sqrt(a->un.u8.e);
|
||||
out->un.u8.f = sqrt(a->un.u8.f);
|
||||
out->un.u8.g = sqrt(a->un.u8.g);
|
||||
out->un.u8.h = sqrt(a->un.u8.h);
|
||||
}
|
||||
static void default_shiftRight_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_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);
|
||||
};
|
||||
#define MAKE_DEFAULT_TABLE(suffix, ty) \
|
||||
static void add_##suffix(MwLLVec* a, MwLLVec* b, MwLLVec* out) { \
|
||||
int i = 0; \
|
||||
for(; i < a->size; i++) { \
|
||||
((ty*)out->buffer)[i] = ((ty*)a->buffer)[i] + ((ty*)b->buffer)[i]; \
|
||||
} \
|
||||
}; \
|
||||
static void sub_##suffix(MwLLVec* a, MwLLVec* b, MwLLVec* out) { \
|
||||
int i = 0; \
|
||||
for(; i < a->size; i++) { \
|
||||
((ty*)out->buffer)[i] = ((ty*)a->buffer)[i] - ((ty*)b->buffer)[i]; \
|
||||
} \
|
||||
}; \
|
||||
static void multiply_##suffix(MwLLVec* a, MwLLVec* b, MwLLVec* out) { \
|
||||
int i = 0; \
|
||||
for(; i < a->size; i++) { \
|
||||
((ty*)out->buffer)[i] = ((ty*)a->buffer)[i] * ((ty*)b->buffer)[i]; \
|
||||
} \
|
||||
}; \
|
||||
static void reciprocal_##suffix(MwLLVec* a, MwLLVec* out) { \
|
||||
int i = 0; \
|
||||
for(; i < a->size; i++) { \
|
||||
((ty*)out->buffer)[i] = pow(((ty*)a->buffer)[i], -1); \
|
||||
} \
|
||||
}; \
|
||||
static void squareRoot_##suffix(MwLLVec* a, MwLLVec* out) { \
|
||||
int i = 0; \
|
||||
for(; i < a->size; i++) { \
|
||||
((ty*)out->buffer)[i] = sqrt(((ty*)a->buffer)[i]); \
|
||||
} \
|
||||
} \
|
||||
static void shiftRight_##suffix(MwLLVec* a, MwLLVec* b, MwLLVec* out) { \
|
||||
int i = 0; \
|
||||
for(; i < a->size; i++) { \
|
||||
((ty*)out->buffer)[i] = ((ty*)a->buffer)[i] >> ((ty*)b->buffer)[i]; \
|
||||
} \
|
||||
}; \
|
||||
static void shiftLeft_##suffix(MwLLVec* a, MwLLVec* b, MwLLVec* out) { \
|
||||
int i = 0; \
|
||||
for(; i < a->size; i++) { \
|
||||
((ty*)out->buffer)[i] = ((ty*)a->buffer)[i] << ((ty*)b->buffer)[i]; \
|
||||
} \
|
||||
} \
|
||||
static void equal_##suffix(MwLLVec* a, MwLLVec* b, MwLLVec* out) { \
|
||||
int i = 0; \
|
||||
for(; i < a->size; i++) { \
|
||||
((ty*)out->buffer)[i] = ((ty*)a->buffer)[i] == ((ty*)b->buffer)[i]; \
|
||||
} \
|
||||
}; \
|
||||
static void greaterThen_##suffix(MwLLVec* a, MwLLVec* b, MwLLVec* out) { \
|
||||
int i = 0; \
|
||||
for(; i < a->size; i++) { \
|
||||
((ty*)out->buffer)[i] = ((ty*)a->buffer)[i] >= ((ty*)b->buffer)[i]; \
|
||||
} \
|
||||
}; \
|
||||
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};
|
||||
|
||||
static void default_shiftRight_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_shiftLeft_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_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};
|
||||
MAKE_DEFAULT_TABLE(u8, MwU8);
|
||||
MAKE_DEFAULT_TABLE(u16, MwU16);
|
||||
MAKE_DEFAULT_TABLE(u32, MwU32);
|
||||
MAKE_DEFAULT_TABLE(u64, MwU64);
|
||||
MAKE_DEFAULT_TABLE(i8, MwI8);
|
||||
MAKE_DEFAULT_TABLE(i16, MwI16);
|
||||
MAKE_DEFAULT_TABLE(i32, MwI32);
|
||||
MAKE_DEFAULT_TABLE(i64, MwI64);
|
||||
|
||||
static void default_add_u32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
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_sub_u32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
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_multiply_u32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
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 MwLLMathVTable* defaultMultiTable[MwLLVecType_Max] = {
|
||||
&table_u8, /*MwLLVecTypeU8*/
|
||||
&table_u16, /*MwLLVecTypeU16*/
|
||||
&table_u32, /*MwLLVecTypeU32*/
|
||||
&table_u64, /*MwLLVecTypeU64*/
|
||||
&table_i8, /*MwLLVecTypeI8*/
|
||||
&table_i16, /*MwLLVecTypeI16*/
|
||||
&table_i32, /*MwLLVecTypeI32*/
|
||||
&table_i64, /*MwLLVecTypeI64*/
|
||||
};
|
||||
static void default_squareRoot_u32(MwLLVec* a, MwLLVec* out) {
|
||||
out->un.u32.a = sqrt(a->un.u32.a);
|
||||
out->un.u32.b = sqrt(a->un.u32.b);
|
||||
};
|
||||
|
||||
static void default_shiftRight_u32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
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_shiftLeft_u32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
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_equal_u32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
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_greaterThen_u32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
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 MwLLMathVTable table_u32 = {
|
||||
default_add_u32,
|
||||
default_multiply_u32,
|
||||
default_sub_u32,
|
||||
default_reciprocal_u32,
|
||||
default_squareRoot_u32,
|
||||
NULL,
|
||||
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;
|
||||
void default_apply(MwLLVec* v) {
|
||||
switch(v->ty) {
|
||||
case MwLLVecTypeU8:
|
||||
v->vtable = table_u8;
|
||||
break;
|
||||
case MwLLVecTypeU16:
|
||||
v->vtable = table_u16;
|
||||
break;
|
||||
case MwLLVecTypeU32:
|
||||
v->vtable = table_u32;
|
||||
break;
|
||||
case MwLLVecTypeU64:
|
||||
v->vtable = table_u64;
|
||||
break;
|
||||
case MwLLVecTypeI8:
|
||||
v->vtable = table_i8;
|
||||
break;
|
||||
case MwLLVecTypeI16:
|
||||
v->vtable = table_i16;
|
||||
break;
|
||||
case MwLLVecTypeI32:
|
||||
v->vtable = table_i32;
|
||||
break;
|
||||
case MwLLVecTypeI64:
|
||||
v->vtable = table_i64;
|
||||
break;
|
||||
case MwLLVecType_Max:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
214
src/math/math.c
214
src/math/math.c
@@ -3,45 +3,17 @@
|
||||
|
||||
#include "math_internal.h"
|
||||
|
||||
MwLLVec _MwLLVecCreateGeneric(int ty, ...) {
|
||||
MwLLVecUnion un;
|
||||
MwLLVec vec;
|
||||
va_list va;
|
||||
#if defined(MwLLMath_x86)
|
||||
struct x86Features {
|
||||
MwBool mmx;
|
||||
MwBool sse2;
|
||||
};
|
||||
|
||||
va_start(va, ty);
|
||||
|
||||
// clang-format off
|
||||
#define _A_B(ty) un.ty.a = va_arg(va, int); un.ty.b = va_arg(va, int);
|
||||
#define _C_D(ty) un.ty.c = va_arg(va, int); un.ty.d = va_arg(va, int);
|
||||
#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;
|
||||
static struct x86Features
|
||||
getCPUFeatures(void) {
|
||||
MwU32 _eax = 1;
|
||||
MwU32 _edx;
|
||||
struct x86Features features;
|
||||
|
||||
#ifdef __WATCOMC__
|
||||
__asm {
|
||||
@@ -56,87 +28,159 @@ static MwU32 getCPUFeatures(void) {
|
||||
: "a"(1) : "ebx", "ecx");
|
||||
#endif
|
||||
|
||||
return _edx;
|
||||
if(_edx & FEATX86_MMX) {
|
||||
features.mmx = MwTRUE;
|
||||
}
|
||||
if(_edx & FEATX86_SSE2) {
|
||||
features.sse2 = MwTRUE;
|
||||
}
|
||||
return features;
|
||||
}
|
||||
#endif
|
||||
|
||||
static MwLLMathVTable** mwLLMultiTable;
|
||||
static MwLLMathVTable* multiTableSetupAndGet(int ty);
|
||||
static MwLLMathVTable* multiTableGet(int ty);
|
||||
|
||||
static MwLLMathVTable* (*mwLLmathFunc)(int ty) = multiTableSetupAndGet;
|
||||
|
||||
static MwLLMathVTable* getMultiTable(int ty) {
|
||||
return mwLLmathFunc(ty);
|
||||
static int round_multiple(int num, int mul) {
|
||||
return ((num + mul - 1) / mul) * mul;
|
||||
}
|
||||
|
||||
static MwLLMathVTable* multiTableSetupAndGet(int ty) {
|
||||
#if defined(MwLLMathMMX)
|
||||
MwU32 features;
|
||||
#endif
|
||||
MwLLVec* MwLLVaVecCreate(int ty, MwU64 size, ...) {
|
||||
struct x86Features features = getCPUFeatures();
|
||||
MwLLVec* vec = malloc(sizeof(MwLLVec));
|
||||
va_list va;
|
||||
int i = 0;
|
||||
int size_rounded = size;
|
||||
|
||||
mwLLMultiTable = default_multi_table();
|
||||
memset(vec, 0, sizeof(MwLLVec));
|
||||
|
||||
#if defined(MwLLMathMMX)
|
||||
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");
|
||||
vec->size = size;
|
||||
|
||||
if(features & FEATX86_MMX) {
|
||||
mmx_apply(mwLLMultiTable);
|
||||
#ifdef MwLLMath_x86
|
||||
if(features.mmx) {
|
||||
size_rounded = round_multiple(size, 64);
|
||||
}
|
||||
#endif
|
||||
|
||||
mwLLmathFunc = multiTableGet;
|
||||
va_start(va, size);
|
||||
|
||||
return mwLLMultiTable[ty];
|
||||
}
|
||||
static MwLLMathVTable* multiTableGet(int ty) {
|
||||
return mwLLMultiTable[ty];
|
||||
switch(ty) {
|
||||
case MwLLVecTypeU8:
|
||||
case MwLLVecTypeI8:
|
||||
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) {
|
||||
assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty);
|
||||
getMultiTable(a->ty)->Add(a, b, out);
|
||||
dbg_assert(a->size == b->size && a->size == out->size && b->size && out->size);
|
||||
a->vtable.add(a, b, out);
|
||||
}
|
||||
void MwLLMathSub(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty);
|
||||
getMultiTable(a->ty)->Sub(a, b, out);
|
||||
dbg_assert(a->size == b->size && a->size == out->size && b->size && out->size);
|
||||
a->vtable.sub(a, b, out);
|
||||
}
|
||||
void MwLLMathMultiply(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty);
|
||||
getMultiTable(a->ty)->Multiply(a, b, out);
|
||||
dbg_assert(a->size == b->size && a->size == out->size && b->size && out->size);
|
||||
a->vtable.multiply(a, b, out);
|
||||
}
|
||||
void MwLLMathReciprocal(MwLLVec* a, MwLLVec* out) {
|
||||
assert(a->ty == out->ty);
|
||||
getMultiTable(a->ty)->Reciprocal(a, out);
|
||||
dbg_assert(a->size == out->size);
|
||||
a->vtable.reciprocal(a, out);
|
||||
}
|
||||
void MwLLMathSquareRoot(MwLLVec* a, MwLLVec* out) {
|
||||
assert(a->ty == out->ty);
|
||||
getMultiTable(a->ty)->SquareRoot(a, out);
|
||||
dbg_assert(a->size == out->size);
|
||||
a->vtable.squareRoot(a, out);
|
||||
}
|
||||
|
||||
void MwLLMathShiftRight(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty);
|
||||
getMultiTable(a->ty)->ShiftRight(a, b, out);
|
||||
dbg_assert(a->size == b->size && a->size == out->size && b->size && out->size);
|
||||
a->vtable.shiftRight(a, b, out);
|
||||
}
|
||||
void MwLLMathShiftLeft(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty);
|
||||
getMultiTable(a->ty)->ShiftLeft(a, b, out);
|
||||
dbg_assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty);
|
||||
a->vtable.shiftLeft(a, b, out);
|
||||
}
|
||||
void MwLLMathEqual(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty);
|
||||
getMultiTable(a->ty)->Equal(a, b, out);
|
||||
dbg_assert(a->size == b->size && a->size == out->size && b->size && out->size);
|
||||
}
|
||||
void MwLLMathGreaterThen(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty);
|
||||
getMultiTable(a->ty)->GreaterThen(a, b, out);
|
||||
dbg_assert(a->size == b->size && a->size == out->size && b->size && out->size);
|
||||
a->vtable.shiftRight(a, b, 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) {
|
||||
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/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;
|
||||
|
||||
MwLLMathVTable** default_multi_table(void);
|
||||
void mmx_apply(MwLLMathVTable**);
|
||||
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);
|
||||
};
|
||||
|
||||
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
|
||||
|
||||
136
src/math/mmx.c
136
src/math/mmx.c
@@ -1,111 +1,129 @@
|
||||
/* $Id$ */
|
||||
#include <Mw/LowLevelMath.h>
|
||||
|
||||
#ifdef MwLLMathMMX
|
||||
#ifdef MwLLMath_x86
|
||||
#include "math_internal.h"
|
||||
#include <mmintrin.h>
|
||||
|
||||
#define DO_MMX_INTRINSIC(intrin, _ty, _rty, _tyn) \
|
||||
__m64 m = intrin(*(__m64*)&a->un._ty, *(__m64*)&b->un._ty); \
|
||||
struct _tyn* t = (struct _tyn*)&m; \
|
||||
out->un._rty = *t;
|
||||
#define DO_MMX_INTRINSIC(intrin, _ty, _cty) \
|
||||
int i = 0; \
|
||||
for(; i < a->size; i += 8) { \
|
||||
__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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
DO_MMX_INTRINSIC(_m_pcmpgtd, u32, u32, _MwLLVecDataU32x2);
|
||||
DO_MMX_INTRINSIC(_m_pcmpgtd, i32, MwI16);
|
||||
}
|
||||
|
||||
void mmx_apply(MwLLMathVTable** t) {
|
||||
t[_MwLLVecTypeU8x8]->Add = mmx_add8;
|
||||
t[_MwLLVecTypeU8x8]->Sub = mmx_sub8;
|
||||
// t[_MwLLVecTypeU8x8]->GreaterThen = mmx_greaterThen8;
|
||||
t[_MwLLVecTypeU8x8]->Equal = mmx_equal8;
|
||||
t[_MwLLVecTypeU16x4]->Add = mmx_add16;
|
||||
t[_MwLLVecTypeU16x4]->Sub = mmx_sub16;
|
||||
t[_MwLLVecTypeU16x4]->ShiftLeft = mmx_shiftLeft16;
|
||||
t[_MwLLVecTypeU16x4]->ShiftRight = mmx_shiftRight16;
|
||||
// t[_MwLLVecTypeU16x4]->GreaterThen = mmx_greaterThen16;
|
||||
t[_MwLLVecTypeU16x4]->Equal = mmx_equal16;
|
||||
t[_MwLLVecTypeU32x2]->Add = mmx_add32;
|
||||
t[_MwLLVecTypeU32x2]->Sub = mmx_sub32;
|
||||
t[_MwLLVecTypeU32x2]->ShiftLeft = mmx_shiftLeft32;
|
||||
t[_MwLLVecTypeU32x2]->ShiftRight = mmx_shiftRight32;
|
||||
// t[_MwLLVecTypeU32x2]->GreaterThen = mmx_greaterThen32;
|
||||
t[_MwLLVecTypeU32x2]->Equal = mmx_equal32;
|
||||
|
||||
t[_MwLLVecTypeU8x8]->Add = mmx_addi8;
|
||||
t[_MwLLVecTypeU8x8]->Sub = mmx_subi8;
|
||||
t[_MwLLVecTypeI8x8]->GreaterThen = mmx_greaterTheni8;
|
||||
t[_MwLLVecTypeI8x8]->Equal = mmx_equal8;
|
||||
t[_MwLLVecTypeU16x4]->Add = mmx_addi16;
|
||||
t[_MwLLVecTypeU16x4]->Sub = mmx_subi16;
|
||||
t[_MwLLVecTypeI16x4]->ShiftLeft = mmx_shiftLeft16;
|
||||
t[_MwLLVecTypeI16x4]->ShiftRight = mmx_shiftRight16;
|
||||
t[_MwLLVecTypeI16x4]->GreaterThen = mmx_greaterTheni16;
|
||||
t[_MwLLVecTypeI16x4]->Equal = mmx_equal16;
|
||||
t[_MwLLVecTypeI32x2]->Add = mmx_add32;
|
||||
t[_MwLLVecTypeI32x2]->Sub = mmx_sub32;
|
||||
t[_MwLLVecTypeI32x2]->ShiftLeft = mmx_shiftLeft32;
|
||||
t[_MwLLVecTypeI32x2]->ShiftRight = mmx_shiftRight32;
|
||||
t[_MwLLVecTypeI32x2]->GreaterThen = mmx_greaterTheni32;
|
||||
t[_MwLLVecTypeI32x2]->Equal = mmx_equal32;
|
||||
void mmx_apply(MwLLVec* vec) {
|
||||
switch(vec->ty) {
|
||||
case MwLLVecTypeU8:
|
||||
vec->vtable.add = mmx_add8;
|
||||
vec->vtable.sub = mmx_sub8;
|
||||
vec->vtable.equal = mmx_equal8;
|
||||
break;
|
||||
case MwLLVecTypeU16:
|
||||
vec->vtable.add = mmx_add16;
|
||||
vec->vtable.sub = mmx_sub16;
|
||||
vec->vtable.shiftLeft = mmx_shiftLeft16;
|
||||
vec->vtable.shiftRight = mmx_shiftRight16;
|
||||
vec->vtable.equal = mmx_equal16;
|
||||
break;
|
||||
case MwLLVecTypeU32:
|
||||
vec->vtable.add = mmx_add32;
|
||||
vec->vtable.sub = mmx_sub32;
|
||||
vec->vtable.shiftLeft = mmx_shiftLeft32;
|
||||
vec->vtable.shiftRight = mmx_shiftRight32;
|
||||
vec->vtable.equal = mmx_equal32;
|
||||
break;
|
||||
case MwLLVecTypeU64:
|
||||
break;
|
||||
case MwLLVecTypeI8:
|
||||
vec->vtable.add = mmx_addi8;
|
||||
vec->vtable.sub = mmx_subi8;
|
||||
vec->vtable.greaterThen = mmx_greaterTheni8;
|
||||
vec->vtable.equal = mmx_equal8;
|
||||
break;
|
||||
case MwLLVecTypeI16:
|
||||
vec->vtable.add = mmx_addi16;
|
||||
vec->vtable.sub = mmx_subi16;
|
||||
vec->vtable.shiftLeft = mmx_shiftLeft16;
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user