some redesign
git-svn-id: http://svn2.nishi.boats/svn/milsko/trunk@572 b9cfdab3-6d41-4d17-bbe4-086880011989
This commit is contained in:
parent
95771fddd9
commit
263e26ceb9
24 changed files with 113 additions and 720 deletions
|
|
@ -281,8 +281,17 @@ void MwLLLine(MwLL handle, MwPoint* points, MwLLColor color) {
|
|||
}
|
||||
|
||||
MwLLColor MwLLAllocColor(MwLL handle, int r, int g, int b) {
|
||||
MwLLColor c = malloc(sizeof(*c));
|
||||
HDC dc = GetDC(handle->hWnd);
|
||||
MwLLColor c = malloc(sizeof(*c));
|
||||
|
||||
c->brush = NULL;
|
||||
|
||||
MwLLColorUpdate(handle, c, r, g, b);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void MwLLColorUpdate(MwLL handle, MwLLColor c, int r, int g, int b) {
|
||||
HDC dc = GetDC(handle->hWnd);
|
||||
|
||||
if(r > 255) r = 255;
|
||||
if(g > 255) g = 255;
|
||||
|
|
@ -291,14 +300,13 @@ MwLLColor MwLLAllocColor(MwLL handle, int r, int g, int b) {
|
|||
if(g < 0) g = 0;
|
||||
if(b < 0) b = 0;
|
||||
|
||||
if(c->brush != NULL) DeleteObject(c->brush);
|
||||
c->brush = CreateSolidBrush(GetNearestColor(dc, RGB(r, g, b)));
|
||||
c->red = r;
|
||||
c->green = g;
|
||||
c->blue = b;
|
||||
|
||||
ReleaseDC(handle->hWnd, dc);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void MwLLFreeColor(MwLLColor color) {
|
||||
|
|
@ -366,16 +374,9 @@ MwLLPixmap MwLLCreatePixmap(MwLL handle, unsigned char* data, int width, int hei
|
|||
MwLLPixmap r = malloc(sizeof(*r));
|
||||
HDC dc = GetDC(handle->hWnd);
|
||||
BITMAPINFOHEADER bmih;
|
||||
RGBQUAD* quad;
|
||||
int y, x;
|
||||
int w = (width + (16 - (width % 16))) / 8;
|
||||
WORD* words;
|
||||
WORD* words2;
|
||||
|
||||
if(16 * (width / 16) == width) w -= 2;
|
||||
|
||||
words = malloc(w * height);
|
||||
words2 = malloc(w * height);
|
||||
r->data_buffer = malloc(width * height * 4);
|
||||
memcpy(r->data_buffer, data, 4 * width * height);
|
||||
|
||||
r->width = width;
|
||||
r->height = height;
|
||||
|
|
@ -392,16 +393,36 @@ MwLLPixmap MwLLCreatePixmap(MwLL handle, unsigned char* data, int width, int hei
|
|||
bmih.biClrUsed = 0;
|
||||
bmih.biClrImportant = 0;
|
||||
|
||||
r->hBitmap = CreateDIBSection(dc, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, (void**)&quad, NULL, (DWORD)0);
|
||||
r->hBitmap = CreateDIBSection(dc, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, (void**)&r->quad, NULL, (DWORD)0);
|
||||
|
||||
memset(words, 0, w * height);
|
||||
memset(words2, 0, w * height);
|
||||
for(y = 0; y < height; y++) {
|
||||
r->hMask = NULL;
|
||||
r->hMask2 = NULL;
|
||||
|
||||
ReleaseDC(handle->hWnd, dc);
|
||||
|
||||
MwLLPixmapUpdate(r);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void MwLLPixmapUpdate(MwLLPixmap r) {
|
||||
int y, x;
|
||||
int w = (r->width + (16 - (r->width % 16))) / 8;
|
||||
WORD* words;
|
||||
WORD* words2;
|
||||
|
||||
if(16 * (r->width / 16) == r->width) w -= 2;
|
||||
|
||||
words = malloc(w * r->height);
|
||||
words2 = malloc(w * r->height);
|
||||
memset(words, 0, w * r->height);
|
||||
memset(words2, 0, w * r->height);
|
||||
for(y = 0; y < r->height; y++) {
|
||||
BYTE* l = (BYTE*)&words[y * (w / 2)];
|
||||
BYTE* l2 = (BYTE*)&words2[y * (w / 2)];
|
||||
for(x = 0; x < width; x++) {
|
||||
RGBQUAD* q = &quad[y * width + x];
|
||||
unsigned char* px = &data[(y * width + x) * 4];
|
||||
for(x = 0; x < r->width; x++) {
|
||||
RGBQUAD* q = &r->quad[y * r->width + x];
|
||||
unsigned char* px = &r->data_buffer[(y * r->width + x) * 4];
|
||||
|
||||
q->rgbRed = px[0];
|
||||
q->rgbGreen = px[1];
|
||||
|
|
@ -415,18 +436,18 @@ MwLLPixmap MwLLCreatePixmap(MwLL handle, unsigned char* data, int width, int hei
|
|||
}
|
||||
}
|
||||
|
||||
r->hMask = CreateBitmap(width, height, 1, 1, words);
|
||||
r->hMask2 = CreateBitmap(width, height, 1, 1, words2);
|
||||
if(r->hMask != NULL) DeleteObject(r->hMask);
|
||||
if(r->hMask2 != NULL) DeleteObject(r->hMask2);
|
||||
|
||||
r->hMask = CreateBitmap(r->width, r->height, 1, 1, words);
|
||||
r->hMask2 = CreateBitmap(r->width, r->height, 1, 1, words2);
|
||||
|
||||
free(words);
|
||||
free(words2);
|
||||
|
||||
ReleaseDC(handle->hWnd, dc);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void MwLLDestroyPixmap(MwLLPixmap pixmap) {
|
||||
free(pixmap->data_buffer);
|
||||
DeleteObject(pixmap->hMask);
|
||||
DeleteObject(pixmap->hMask2);
|
||||
DeleteObject(pixmap->hBitmap);
|
||||
|
|
|
|||
|
|
@ -45,11 +45,12 @@ struct _MwLLColor {
|
|||
struct _MwLLPixmap {
|
||||
int width;
|
||||
int height;
|
||||
unsigned char* data_scratch_buf;
|
||||
unsigned char* data_buffer;
|
||||
|
||||
HBITMAP hBitmap;
|
||||
HBITMAP hMask;
|
||||
HBITMAP hMask2;
|
||||
RGBQUAD* quad;
|
||||
HBITMAP hBitmap;
|
||||
HBITMAP hMask;
|
||||
HBITMAP hMask2;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -437,8 +437,8 @@ 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);
|
||||
r->data_buffer = malloc(4 * width * height);
|
||||
memcpy(r->data_buffer, data, 4 * width * height);
|
||||
|
||||
XGetWindowAttributes(handle->display, handle->window, &attr);
|
||||
|
||||
|
|
@ -447,25 +447,26 @@ MwLLPixmap MwLLCreatePixmap(MwLL handle, unsigned char* data, int width, int hei
|
|||
r->height = height;
|
||||
r->display = handle->display;
|
||||
r->data = malloc(sizeof(unsigned long) * width * height);
|
||||
r->handle = handle;
|
||||
|
||||
r->use_render = XRenderQueryExtension(handle->display, &evbase, &erbase) ? 1 : 0;
|
||||
|
||||
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);
|
||||
|
||||
MwLLPixmapUpdate(handle, r);
|
||||
MwLLPixmapUpdate(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
void MwLLPixmapUpdate(MwLL handle, MwLLPixmap r) {
|
||||
int y, x;
|
||||
void MwLLPixmapUpdate(MwLLPixmap r) {
|
||||
int y, x;
|
||||
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];
|
||||
MwLLColor c = NULL;
|
||||
unsigned long p;
|
||||
unsigned char* px = &r->data_buffer[(y * r->width + x) * 4];
|
||||
MwLLColor c = NULL;
|
||||
unsigned long p;
|
||||
|
||||
c = MwLLAllocColor(handle, px[0], px[1], px[2]);
|
||||
c = MwLLAllocColor(r->handle, px[0], px[1], px[2]);
|
||||
p = c->pixel;
|
||||
MwLLFreeColor(c);
|
||||
|
||||
|
|
@ -486,11 +487,10 @@ void MwLLPixmapUpdate(MwLL handle, MwLLPixmap r) {
|
|||
}
|
||||
|
||||
void MwLLDestroyPixmap(MwLLPixmap pixmap) {
|
||||
if(pixmap->image != NULL) {
|
||||
XDestroyImage(pixmap->image);
|
||||
XDestroyImage(pixmap->mask);
|
||||
free(pixmap->data);
|
||||
}
|
||||
free(pixmap->data_buf);
|
||||
XDestroyImage(pixmap->image);
|
||||
XDestroyImage(pixmap->mask);
|
||||
free(pixmap->data);
|
||||
|
||||
free(pixmap);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,10 +55,11 @@ struct _MwLLPixmap {
|
|||
int width;
|
||||
int height;
|
||||
unsigned char* data;
|
||||
unsigned char* data_buf;
|
||||
unsigned char* data_buffer;
|
||||
|
||||
int depth;
|
||||
|
||||
MwLL handle;
|
||||
int use_render;
|
||||
Display* display;
|
||||
XImage* image;
|
||||
|
|
|
|||
|
|
@ -2,10 +2,9 @@
|
|||
#include <Mw/Milsko.h>
|
||||
|
||||
#include "color_picker.h"
|
||||
#include <Mw/LowLevelMath.h>
|
||||
|
||||
static void hsv2rgb(MwU32 h, MwU32 s, MwU32 v, MwU32* r, MwU32* g, MwU32* b) {
|
||||
MwU8 sextant = h >> 8;
|
||||
MwU8 sextant = h >> 8;
|
||||
MwU16 ww;
|
||||
MwU32 h_fraction, d;
|
||||
|
||||
|
|
@ -61,12 +60,12 @@ static void hsv2rgb(MwU32 h, MwU32 s, MwU32 v, MwU32* r, MwU32* g, MwU32* b) {
|
|||
}
|
||||
|
||||
static void color_picker_image_update(color_picker* picker) {
|
||||
int y, x;
|
||||
int y, x;
|
||||
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);
|
||||
int i = ((y * PICKER_SIZE) + x) * 4;
|
||||
int _x = x - (PICKER_SIZE / 2);
|
||||
int _y = y - (PICKER_SIZE / 2);
|
||||
double dist;
|
||||
|
||||
if(picker->dist_table[y][x] == 0) {
|
||||
|
|
@ -81,6 +80,7 @@ static void color_picker_image_update(color_picker* picker) {
|
|||
picker->color_picker_image_data[i + 3] = 0;
|
||||
} else {
|
||||
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);
|
||||
|
|
@ -100,7 +100,6 @@ static void color_picker_image_update(color_picker* picker) {
|
|||
hsv_v = picker->hue_table[y][x];
|
||||
hsv_v.v = HSV_VAL_MAX - (picker->value * HSV_VAL_MAX);
|
||||
|
||||
MwRGB color;
|
||||
hsv2rgb(hsv_v.h, hsv_v.s, hsv_v.v, &color.red, &color.green, &color.blue);
|
||||
|
||||
picker->color_picker_image_data[i] = color.red;
|
||||
|
|
@ -137,9 +136,9 @@ static void color_picker_click(MwWidget handle, void* user, void* call) {
|
|||
|
||||
i = ((mouse->point.y * PICKER_SIZE) + mouse->point.x) * 4;
|
||||
|
||||
picker->chosen_color.red = picker->color_picker_image_data[i];
|
||||
picker->chosen_color.red = picker->color_picker_image_data[i];
|
||||
picker->chosen_color.green = picker->color_picker_image_data[i + 1];
|
||||
picker->chosen_color.blue = picker->color_picker_image_data[i + 2];
|
||||
picker->chosen_color.blue = picker->color_picker_image_data[i + 2];
|
||||
|
||||
sprintf(hexColor, "#%02X%02X%02X", picker->chosen_color.red, picker->chosen_color.green, picker->chosen_color.blue);
|
||||
|
||||
|
|
|
|||
|
|
@ -36,19 +36,19 @@ struct _MwHSV {
|
|||
};
|
||||
|
||||
struct _color_picker {
|
||||
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];
|
||||
MwRGB chosen_color;
|
||||
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];
|
||||
MwRGB chosen_color;
|
||||
};
|
||||
|
||||
color_picker* color_picker_setup(MwWidget parent, int w, int h);
|
||||
|
|
|
|||
|
|
@ -691,7 +691,7 @@ void MwReloadRaw(MwWidget handle, unsigned char* rgb, int width, int height, MwL
|
|||
|
||||
if(handle->bgcolor == NULL) MwLLFreeColor(base);
|
||||
|
||||
MwLLPixmapUpdate(handle->lowlevel, px);
|
||||
MwLLPixmapUpdate(px);
|
||||
}
|
||||
|
||||
void MwGetColor(MwLLColor color, int* red, int* green, int* blue) {
|
||||
|
|
|
|||
|
|
@ -1,112 +0,0 @@
|
|||
/* $Id$ */
|
||||
#include <Mw/LowLevelMath.h>
|
||||
#include "math_internal.h"
|
||||
|
||||
#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};
|
||||
|
||||
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);
|
||||
|
||||
#if 0
|
||||
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*/
|
||||
};
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
}
|
||||
186
src/math/math.c
186
src/math/math.c
|
|
@ -1,186 +0,0 @@
|
|||
/* $Id$ */
|
||||
#include <Mw/LowLevelMath.h>
|
||||
|
||||
#include "math_internal.h"
|
||||
|
||||
#if defined(MwLLMath_x86)
|
||||
struct x86Features {
|
||||
MwBool mmx;
|
||||
MwBool sse2;
|
||||
};
|
||||
|
||||
static struct x86Features
|
||||
getCPUFeatures(void) {
|
||||
MwU32 _eax = 1;
|
||||
MwU32 _edx;
|
||||
struct x86Features features;
|
||||
|
||||
#ifdef __WATCOMC__
|
||||
__asm {
|
||||
mov eax, _eax
|
||||
cpuid
|
||||
mov _eax, eax
|
||||
mov _edx, edx
|
||||
}
|
||||
#else
|
||||
asm volatile(
|
||||
"cpuid" : "=a"(_eax), "=d"(_edx)
|
||||
: "a"(1) : "ebx", "ecx");
|
||||
#endif
|
||||
|
||||
if(_edx & FEATX86_MMX) {
|
||||
features.mmx = MwTRUE;
|
||||
}
|
||||
if(_edx & FEATX86_SSE2) {
|
||||
features.sse2 = MwTRUE;
|
||||
}
|
||||
return features;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int round_multiple(int num, int mul) {
|
||||
return ((num + mul - 1) / mul) * mul;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
memset(vec, 0, sizeof(MwLLVec));
|
||||
|
||||
vec->size = size;
|
||||
|
||||
#ifdef MwLLMath_x86
|
||||
if(features.mmx) {
|
||||
size_rounded = round_multiple(size, 64);
|
||||
}
|
||||
#endif
|
||||
|
||||
va_start(va, size);
|
||||
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
dbg_assert(a->size == out->size);
|
||||
a->vtable.reciprocal(a, out);
|
||||
}
|
||||
void MwLLMathSquareRoot(MwLLVec* a, MwLLVec* out) {
|
||||
dbg_assert(a->size == out->size);
|
||||
a->vtable.squareRoot(a, out);
|
||||
}
|
||||
|
||||
void MwLLMathShiftRight(MwLLVec* a, MwLLVec* b, MwLLVec* 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) {
|
||||
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) {
|
||||
dbg_assert(a->size == b->size && a->size == out->size && b->size && out->size);
|
||||
}
|
||||
void MwLLMathGreaterThen(MwLLVec* a, MwLLVec* b, MwLLVec* 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) {
|
||||
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) {
|
||||
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];
|
||||
};
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
/* $Id$ */
|
||||
|
||||
#ifndef __MW_LOWLEVEL_INTERNAL_MATH_H__
|
||||
#define __MW_LOWLEVEL_INTERNAL_MATH_H__
|
||||
|
||||
#include <Mw/BaseTypes.h>
|
||||
#include <Mw/LowLevelMath.h>
|
||||
|
||||
typedef struct _MwLLMathVTable 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
|
||||
129
src/math/mmx.c
129
src/math/mmx.c
|
|
@ -1,129 +0,0 @@
|
|||
/* $Id$ */
|
||||
#include <Mw/LowLevelMath.h>
|
||||
|
||||
#ifdef MwLLMath_x86
|
||||
#include "math_internal.h"
|
||||
#include <mmintrin.h>
|
||||
|
||||
#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, MwU8)
|
||||
}
|
||||
static void mmx_sub8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
DO_MMX_INTRINSIC(_m_psubb, u8, MwU8);
|
||||
}
|
||||
static void mmx_equal8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
DO_MMX_INTRINSIC(_m_pcmpeqb, u8, MwU8);
|
||||
}
|
||||
static void mmx_add16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
DO_MMX_INTRINSIC(_m_paddw, u16, MwU16);
|
||||
}
|
||||
static void mmx_sub16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
DO_MMX_INTRINSIC(_m_psubw, u16, MwU16);
|
||||
}
|
||||
static void mmx_shiftRight16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
DO_MMX_INTRINSIC(_m_psrlw, u16, MwU16);
|
||||
}
|
||||
static void mmx_shiftLeft16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
DO_MMX_INTRINSIC(_m_psllw, u16, MwU16);
|
||||
}
|
||||
static void mmx_equal16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
DO_MMX_INTRINSIC(_m_pcmpeqw, u16, MwU16);
|
||||
}
|
||||
|
||||
static void mmx_add32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
DO_MMX_INTRINSIC(_m_paddd, u32, MwU32);
|
||||
}
|
||||
static void mmx_sub32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
DO_MMX_INTRINSIC(_m_psubd, u32, MwU32);
|
||||
}
|
||||
static void mmx_shiftRight32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
DO_MMX_INTRINSIC(_m_psrld, u32, MwU32);
|
||||
}
|
||||
static void mmx_shiftLeft32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
DO_MMX_INTRINSIC(_m_pslld, u32, MwU32);
|
||||
}
|
||||
static void mmx_equal32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
DO_MMX_INTRINSIC(_m_pcmpeqw, u32, MwU32);
|
||||
}
|
||||
|
||||
static void mmx_addi8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
DO_MMX_INTRINSIC(_m_paddsb, i8, MwI8);
|
||||
}
|
||||
static void mmx_subi8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
DO_MMX_INTRINSIC(_m_psubsb, i8, MwI8);
|
||||
}
|
||||
static void mmx_addi16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
DO_MMX_INTRINSIC(_m_paddsw, i16, MwI16);
|
||||
}
|
||||
static void mmx_subi16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
DO_MMX_INTRINSIC(_m_psubsw, i16, MwI16);
|
||||
}
|
||||
static void mmx_greaterTheni8(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
DO_MMX_INTRINSIC(_m_pcmpgtb, i8, MwI8);
|
||||
}
|
||||
static void mmx_greaterTheni16(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
DO_MMX_INTRINSIC(_m_pcmpgtw, i16, MwI16);
|
||||
}
|
||||
static void mmx_greaterTheni32(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
|
||||
DO_MMX_INTRINSIC(_m_pcmpgtd, i32, MwI16);
|
||||
}
|
||||
|
||||
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
|
||||
Loading…
Add table
Add a link
Reference in a new issue