libdgl/DGLMTX33.H
Gered 62af8575c6 various updates i've left uncommitted for many months
- rename standard integer types to a more familiar (u)int(8/16/32)
- many function/struct renames. i don't _really_ know if what i've done
  for this is better, but it "feels" better to me. many draw/blit
  function names are shorter which is nice, at least. kinda important
  to me because i develop this on a real DOS machine in 80x50 text mode.
- add 'extern "C"' blocks to headers for C++ compiler usage
- draw/pixel color value arguments for functions should all have been
  changed to be uint8 instead of a full 32-bit int. feels right, but
  maybe should've left alone...
- small fix to keyboard handler. noticed a problem on one thinkpad
  laptop. was a result of what i think was a typo in a constant value
  used during the part of the interrupt handler that tells the keyboard
  controller the key event was processed
- fix uncommon potential crash function return in draw_filled_rect
- renamed low-level "direct" assembly functions to "lowlevel_xxx" to
  be a little bit more explicit about what they are
- add some convenience event helper functions for determining event
  types
- add fixed point atan2
- fixed some tabs/spaces inconsistences (should all be spaces now?)
- maybe some other minor things i've forgotten
2020-07-19 19:24:48 -04:00

358 lines
11 KiB
C
Executable file

#ifndef LIBDGL_DGLMTX33_H
#define LIBDGL_DGLMTX33_H
#include <math.h>
#include "dglcmn.h"
#include "dglfixp.h"
#include "dglvec2.h"
#ifdef __cplusplus
extern "C" {
#endif
#define _M33_11 0
#define _M33_12 3
#define _M33_13 6
#define _M33_21 1
#define _M33_22 4
#define _M33_23 7
#define _M33_31 2
#define _M33_32 5
#define _M33_33 8
typedef struct {
fixed m[9];
} MTX33;
static MTX33 mtx33(
fixed m11, fixed m12, fixed m13,
fixed m21, fixed m22, fixed m23,
fixed m31, fixed m32, fixed m33
);
static void mtx33_set(
MTX33 *m,
fixed m11, fixed m12, fixed m13,
fixed m21, fixed m22, fixed m23,
fixed m31, fixed m32, fixed m33
);
static MTX33 mtx33_from_angles(float x, float y, float z);
static MTX33 mtx33_rotation_x(float radians);
static MTX33 mtx33_rotation_y(float radians);
static MTX33 mtx33_rotation_z(float radians);
static MTX33 mtx33_add(MTX33 a, MTX33 b);
static MTX33 mtx33_sub(MTX33 a, MTX33 b);
static MTX33 mtx33_mul(MTX33 a, MTX33 b);
static MTX33 mtx33_scale(MTX33 m, fixed scale);
static fixed mtx33_determinant(MTX33 m);
static MTX33 mtx33_inverse(MTX33 m);
static MTX33 mtx33_transpose(MTX33 m);
static VEC2 mtx33_transform(MTX33 m, VEC2 v);
static MTX33 mtx33_translation_2d(fixed x, fixed y);
static MTX33 mtx33_scaling_2d(fixed x, fixed y);
static MTX33 mtx33_rotation_2d(float radians);
static VEC2 mtx33_transform_2d(MTX33 m, VEC2 v);
#define IDENTITY_MTX33 mtx33(1.0f, 0.0f, 0.0f, \
0.0f, 1.0f, 0.0f, \
0.0f, 0.0f, 1.0f)
// --------------------------------------------------------------------------
static MTX33 mtx33(
fixed m11, fixed m12, fixed m13,
fixed m21, fixed m22, fixed m23,
fixed m31, fixed m32, fixed m33
) {
MTX33 result;
result.m[_M33_11] = m11;
result.m[_M33_12] = m12;
result.m[_M33_13] = m13;
result.m[_M33_21] = m21;
result.m[_M33_22] = m22;
result.m[_M33_23] = m23;
result.m[_M33_31] = m31;
result.m[_M33_32] = m32;
result.m[_M33_33] = m33;
return result;
}
static void mtx33_set(
MTX33 *m,
fixed m11, fixed m12, fixed m13,
fixed m21, fixed m22, fixed m23,
fixed m31, fixed m32, fixed m33
) {
m->m[_M33_11] = m11;
m->m[_M33_12] = m12;
m->m[_M33_13] = m13;
m->m[_M33_21] = m21;
m->m[_M33_22] = m22;
m->m[_M33_23] = m23;
m->m[_M33_31] = m31;
m->m[_M33_32] = m32;
m->m[_M33_33] = m33;
}
static MTX33 mtx33_from_angles(float x, float y, float z) {
MTX33 rx, ry, rz;
rx = mtx33_rotation_x(x);
ry = mtx33_rotation_y(y);
rz = mtx33_rotation_z(z);
return mtx33_mul(mtx33_mul(rz, ry), rx);
}
static MTX33 mtx33_rotation_x(fixed radians) {
MTX33 result;
fixed s, c;
s = FTOFIX(sin(radians));
c = FTOFIX(cos(radians));
result.m[_M33_11] = FP_1;
result.m[_M33_12] = 0;
result.m[_M33_13] = 0;
result.m[_M33_21] = 0;
result.m[_M33_22] = c;
result.m[_M33_23] = -s;
result.m[_M33_31] = 0;
result.m[_M33_32] = s;
result.m[_M33_33] = c;
return result;
}
static MTX33 mtx33_rotation_y(float radians) {
MTX33 result;
fixed s, c;
s = FTOFIX(sin(radians));
c = FTOFIX(cos(radians));
result.m[_M33_11] = c;
result.m[_M33_12] = 0;
result.m[_M33_13] = s;
result.m[_M33_21] = 0;
result.m[_M33_22] = FP_1;
result.m[_M33_23] = 0;
result.m[_M33_31] = -s;
result.m[_M33_32] = 0;
result.m[_M33_33] = c;
return result;
}
static MTX33 mtx33_rotation_z(float radians) {
MTX33 result;
fixed s, c;
s = FTOFIX(sin(radians));
c = FTOFIX(cos(radians));
result.m[_M33_11] = c;
result.m[_M33_12] = -s;
result.m[_M33_13] = 0;
result.m[_M33_21] = s;
result.m[_M33_22] = c;
result.m[_M33_23] = 0;
result.m[_M33_31] = 0;
result.m[_M33_32] = 0;
result.m[_M33_33] = FP_1;
return result;
}
static MTX33 mtx33_add(MTX33 a, MTX33 b) {
MTX33 result;
result.m[_M33_11] = a.m[_M33_11] + b.m[_M33_11];
result.m[_M33_12] = a.m[_M33_12] + b.m[_M33_12];
result.m[_M33_13] = a.m[_M33_13] + b.m[_M33_13];
result.m[_M33_21] = a.m[_M33_21] + b.m[_M33_21];
result.m[_M33_22] = a.m[_M33_22] + b.m[_M33_22];
result.m[_M33_23] = a.m[_M33_23] + b.m[_M33_23];
result.m[_M33_31] = a.m[_M33_31] + b.m[_M33_31];
result.m[_M33_32] = a.m[_M33_32] + b.m[_M33_32];
result.m[_M33_33] = a.m[_M33_33] + b.m[_M33_33];
return result;
}
static MTX33 mtx33_sub(MTX33 a, MTX33 b) {
MTX33 result;
result.m[_M33_11] = a.m[_M33_11] - b.m[_M33_11];
result.m[_M33_12] = a.m[_M33_12] - b.m[_M33_12];
result.m[_M33_13] = a.m[_M33_13] - b.m[_M33_13];
result.m[_M33_21] = a.m[_M33_21] - b.m[_M33_21];
result.m[_M33_22] = a.m[_M33_22] - b.m[_M33_22];
result.m[_M33_23] = a.m[_M33_23] - b.m[_M33_23];
result.m[_M33_31] = a.m[_M33_31] - b.m[_M33_31];
result.m[_M33_32] = a.m[_M33_32] - b.m[_M33_32];
result.m[_M33_33] = a.m[_M33_33] - b.m[_M33_33];
return result;
}
static MTX33 mtx33_mul(MTX33 a, MTX33 b) {
MTX33 result;
result.m[_M33_11] = fix_mul(a.m[_M33_11], b.m[_M33_11]) + fix_mul(a.m[_M33_12], b.m[_M33_21]) + fix_mul(a.m[_M33_13], b.m[_M33_31]);
result.m[_M33_12] = fix_mul(a.m[_M33_11], b.m[_M33_12]) + fix_mul(a.m[_M33_12], b.m[_M33_22]) + fix_mul(a.m[_M33_13], b.m[_M33_32]);
result.m[_M33_13] = fix_mul(a.m[_M33_11], b.m[_M33_13]) + fix_mul(a.m[_M33_12], b.m[_M33_23]) + fix_mul(a.m[_M33_13], b.m[_M33_33]);
result.m[_M33_21] = fix_mul(a.m[_M33_21], b.m[_M33_11]) + fix_mul(a.m[_M33_22], b.m[_M33_21]) + fix_mul(a.m[_M33_23], b.m[_M33_31]);
result.m[_M33_22] = fix_mul(a.m[_M33_21], b.m[_M33_12]) + fix_mul(a.m[_M33_22], b.m[_M33_22]) + fix_mul(a.m[_M33_23], b.m[_M33_32]);
result.m[_M33_23] = fix_mul(a.m[_M33_21], b.m[_M33_13]) + fix_mul(a.m[_M33_22], b.m[_M33_23]) + fix_mul(a.m[_M33_23], b.m[_M33_33]);
result.m[_M33_31] = fix_mul(a.m[_M33_31], b.m[_M33_11]) + fix_mul(a.m[_M33_32], b.m[_M33_21]) + fix_mul(a.m[_M33_33], b.m[_M33_31]);
result.m[_M33_32] = fix_mul(a.m[_M33_31], b.m[_M33_12]) + fix_mul(a.m[_M33_32], b.m[_M33_22]) + fix_mul(a.m[_M33_33], b.m[_M33_32]);
result.m[_M33_33] = fix_mul(a.m[_M33_31], b.m[_M33_13]) + fix_mul(a.m[_M33_32], b.m[_M33_23]) + fix_mul(a.m[_M33_33], b.m[_M33_33]);
return result;
}
static MTX33 mtx33_scale(MTX33 m, fixed scale) {
MTX33 result;
result.m[_M33_11] = fix_mul(m.m[_M33_11], scale);
result.m[_M33_12] = fix_mul(m.m[_M33_12], scale);
result.m[_M33_13] = fix_mul(m.m[_M33_13], scale);
result.m[_M33_21] = fix_mul(m.m[_M33_21], scale);
result.m[_M33_22] = fix_mul(m.m[_M33_22], scale);
result.m[_M33_23] = fix_mul(m.m[_M33_23], scale);
result.m[_M33_31] = fix_mul(m.m[_M33_31], scale);
result.m[_M33_32] = fix_mul(m.m[_M33_32], scale);
result.m[_M33_33] = fix_mul(m.m[_M33_33], scale);
return result;
}
static fixed mtx33_determinant(MTX33 m) {
return
fix_mul(m.m[_M33_11], fix_mul(m.m[_M33_22], m.m[_M33_33])) +
fix_mul(m.m[_M33_12], fix_mul(m.m[_M33_23], m.m[_M33_31])) +
fix_mul(m.m[_M33_13], fix_mul(m.m[_M33_21], m.m[_M33_32])) -
fix_mul(m.m[_M33_11], fix_mul(m.m[_M33_23], m.m[_M33_32])) -
fix_mul(m.m[_M33_12], fix_mul(m.m[_M33_21], m.m[_M33_33])) -
fix_mul(m.m[_M33_13], fix_mul(m.m[_M33_22], m.m[_M33_31]));
}
static MTX33 mtx33_inverse(MTX33 m) {
fixed d;
MTX33 result;
d = mtx33_determinant(m);
if (d == 0)
return IDENTITY_MTX33;
else {
d = fix_div(FP_1, d);
result.m[_M33_11] = fix_mul(d, (fix_mul(m.m[_M33_22], m.m[_M33_33]) - fix_mul(m.m[_M33_32], m.m[_M33_23])));
result.m[_M33_21] = fix_mul(d, (fix_mul(m.m[_M33_31], m.m[_M33_23]) - fix_mul(m.m[_M33_21], m.m[_M33_33])));
result.m[_M33_31] = fix_mul(d, (fix_mul(m.m[_M33_21], m.m[_M33_32]) - fix_mul(m.m[_M33_31], m.m[_M33_22])));
result.m[_M33_21] = fix_mul(d, (fix_mul(m.m[_M33_32], m.m[_M33_13]) - fix_mul(m.m[_M33_12], m.m[_M33_33])));
result.m[_M33_22] = fix_mul(d, (fix_mul(m.m[_M33_11], m.m[_M33_33]) - fix_mul(m.m[_M33_31], m.m[_M33_13])));
result.m[_M33_23] = fix_mul(d, (fix_mul(m.m[_M33_31], m.m[_M33_12]) - fix_mul(m.m[_M33_11], m.m[_M33_32])));
result.m[_M33_31] = fix_mul(d, (fix_mul(m.m[_M33_12], m.m[_M33_23]) - fix_mul(m.m[_M33_22], m.m[_M33_13])));
result.m[_M33_32] = fix_mul(d, (fix_mul(m.m[_M33_21], m.m[_M33_13]) - fix_mul(m.m[_M33_11], m.m[_M33_23])));
result.m[_M33_33] = fix_mul(d, (fix_mul(m.m[_M33_11], m.m[_M33_22]) - fix_mul(m.m[_M33_21], m.m[_M33_12])));
return result;
}
}
static MTX33 mtx33_transpose(MTX33 m) {
MTX33 result;
result.m[_M33_11] = m.m[_M33_11];
result.m[_M33_12] = m.m[_M33_21];
result.m[_M33_13] = m.m[_M33_31];
result.m[_M33_21] = m.m[_M33_12];
result.m[_M33_22] = m.m[_M33_22];
result.m[_M33_23] = m.m[_M33_32];
result.m[_M33_31] = m.m[_M33_13];
result.m[_M33_32] = m.m[_M33_23];
result.m[_M33_33] = m.m[_M33_33];
return result;
}
static VEC2 mtx33_transform(MTX33 m, VEC2 v) {
VEC2 result;
result.x = fix_mul(v.x, m.m[_M33_11]) + fix_mul(v.y, m.m[_M33_12]) + m.m[_M33_13];
result.y = fix_mul(v.x, m.m[_M33_21]) + fix_mul(v.y, m.m[_M33_22]) + m.m[_M33_23];
return result;
}
static MTX33 mtx33_translation_2d(fixed x, fixed y) {
MTX33 result;
result.m[_M33_11] = FP_1;
result.m[_M33_12] = 0;
result.m[_M33_13] = 0;
result.m[_M33_21] = 0;
result.m[_M33_22] = FP_1;
result.m[_M33_23] = 0;
result.m[_M33_31] = x;
result.m[_M33_32] = y;
result.m[_M33_33] = FP_1;
return result;
}
static MTX33 mtx33_scaling_2d(fixed x, fixed y) {
MTX33 result;
result.m[_M33_11] = x;
result.m[_M33_12] = 0;
result.m[_M33_13] = 0;
result.m[_M33_21] = 0;
result.m[_M33_22] = y;
result.m[_M33_23] = 0;
result.m[_M33_31] = 0;
result.m[_M33_32] = 0;
result.m[_M33_33] = FP_1;
return result;
}
static MTX33 mtx33_rotation_2d(float radians) {
return mtx33_rotation_z(radians);
}
static VEC2 mtx33_transform_2d(MTX33 m, VEC2 v) {
VEC2 result;
result.x = fix_mul(v.x, m.m[_M33_11]) + fix_mul(v.y, m.m[_M33_12]) + m.m[_M33_13];
result.y = fix_mul(v.x, m.m[_M33_21]) + fix_mul(v.y, m.m[_M33_22]) + m.m[_M33_23];
result.x += m.m[_M33_31];
result.y += m.m[_M33_32];
return result;
}
#ifdef __cplusplus
}
#endif
#endif