many updates. moved project over to watcom
This commit is contained in:
parent
e5415c977c
commit
123d3b8256
68
DGL.C
68
DGL.C
|
@ -1,68 +1,22 @@
|
|||
#include "dgl.h"
|
||||
#include "keyboard.h"
|
||||
#include "mouse.h"
|
||||
#include "gfx.h"
|
||||
#include "util.h"
|
||||
#include "dglkbrd.h"
|
||||
#include "dglmouse.h"
|
||||
#include "dglgfx.h"
|
||||
#include "dglutil.h"
|
||||
#include <stdlib.h>
|
||||
#include <go32.h>
|
||||
#include <sys/nearptr.h>
|
||||
|
||||
static boolean _initialized = FALSE;
|
||||
static DGL_ERROR _last_error = DGL_NONE;
|
||||
|
||||
boolean dgl_init(void) {
|
||||
if (_initialized) {
|
||||
dgl_set_error(DGL_ALREADY_INIT);
|
||||
return FALSE;
|
||||
}
|
||||
if (__djgpp_nearptr_enable() == 0) {
|
||||
dgl_set_error(DGL_NEARPTR_ENABLE_FAILURE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
srandom((int)sys_clock());
|
||||
|
||||
// first call will return zero, so call here just to "init"
|
||||
sys_clock();
|
||||
sys_ticks();
|
||||
|
||||
if (!video_init())
|
||||
return FALSE;
|
||||
if (!keyboard_init())
|
||||
return FALSE;
|
||||
if (!mouse_init())
|
||||
return FALSE;
|
||||
|
||||
_initialized = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
boolean dgl_shutdown(void) {
|
||||
if (!_initialized)
|
||||
return TRUE; // don't care
|
||||
|
||||
// remove installed services
|
||||
if (!mouse_shutdown())
|
||||
return FALSE;
|
||||
if (!keyboard_shutdown())
|
||||
return FALSE;
|
||||
if (!video_shutdown())
|
||||
return FALSE;
|
||||
|
||||
__djgpp_nearptr_disable();
|
||||
|
||||
_initialized = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DGL_ERROR dgl_last_error(void) {
|
||||
return _last_error;
|
||||
DGL_ERROR err = _last_error;
|
||||
_last_error = DGL_NONE;
|
||||
return err;
|
||||
}
|
||||
|
||||
const char* dgl_last_error_message(void) {
|
||||
switch (_last_error) {
|
||||
case DGL_NONE:
|
||||
return "No error.";
|
||||
return "";
|
||||
case DGL_ALREADY_INIT:
|
||||
return "DGL is already initialized.";
|
||||
case DGL_NEARPTR_ENABLE_FAILURE:
|
||||
|
@ -104,3 +58,9 @@ void dgl_set_error(DGL_ERROR error) {
|
|||
_last_error = error;
|
||||
}
|
||||
|
||||
void dgl_init(void) {
|
||||
atexit(mouse_shutdown);
|
||||
atexit(keyboard_shutdown);
|
||||
atexit(video_shutdown);
|
||||
}
|
||||
|
||||
|
|
33
DGL.H
33
DGL.H
|
@ -1,24 +1,25 @@
|
|||
#ifndef DGL_DGL_H_INCLUDED
|
||||
#define DGL_DGL_H_INCLUDED
|
||||
|
||||
#include "common.h"
|
||||
#include "error.h"
|
||||
#include "dglcmn.h"
|
||||
#include "dglerror.h"
|
||||
|
||||
#include "keyboard.h"
|
||||
#include "mouse.h"
|
||||
#include "gfx.h"
|
||||
#include "clipping.h"
|
||||
#include "draw.h"
|
||||
#include "blit.h"
|
||||
#include "mathext.h"
|
||||
#include "rect.h"
|
||||
#include "vector2.h"
|
||||
#include "matrix33.h"
|
||||
#include "util.h"
|
||||
#include "pcx.h"
|
||||
#include "dglkbrd.h"
|
||||
#include "dglmouse.h"
|
||||
#include "dglgfx.h"
|
||||
#include "dglpal.h"
|
||||
#include "dglclip.h"
|
||||
#include "dgldraw.h"
|
||||
#include "dglblit.h"
|
||||
#include "dglmath.h"
|
||||
#include "dglfixp.h"
|
||||
#include "dglrect.h"
|
||||
#include "dglvec2.h"
|
||||
#include "dglmtx33.h"
|
||||
#include "dglutil.h"
|
||||
#include "dglpcx.h"
|
||||
|
||||
boolean dgl_init(void);
|
||||
boolean dgl_shutdown(void);
|
||||
void dgl_init(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
#include "blit.h"
|
||||
#include "clipping.h"
|
||||
#include "internal.h"
|
||||
#include "dglblit.h"
|
||||
#include "dglclip.h"
|
||||
|
||||
static inline boolean clip_blit(const RECT *dest_clip_region,
|
||||
RECT *src_blit_region,
|
||||
int *dest_x,
|
||||
int *dest_y) {
|
||||
static boolean clip_blit(const RECT *dest_clip_region,
|
||||
RECT *src_blit_region,
|
||||
int *dest_x,
|
||||
int *dest_y) {
|
||||
int dest_clip_right = rect_right(dest_clip_region);
|
||||
int dest_clip_bottom = rect_bottom(dest_clip_region);
|
||||
int offset;
|
||||
|
@ -13,7 +12,7 @@ static inline boolean clip_blit(const RECT *dest_clip_region,
|
|||
// off the left edge?
|
||||
if (*dest_x < dest_clip_region->x) {
|
||||
// completely off the left edge?
|
||||
if ((*dest_x + src_blit_region->width) < dest_clip_region->x)
|
||||
if ((*dest_x + src_blit_region->width - 1) < dest_clip_region->x)
|
||||
return FALSE;
|
||||
|
||||
offset = src_blit_region->x - *dest_x;
|
||||
|
@ -35,7 +34,7 @@ static inline boolean clip_blit(const RECT *dest_clip_region,
|
|||
// off the top edge?
|
||||
if (*dest_y < dest_clip_region->y) {
|
||||
// completely off the top edge?
|
||||
if ((*dest_y + src_blit_region->height) < dest_clip_region->y)
|
||||
if ((*dest_y + src_blit_region->height - 1) < dest_clip_region->y)
|
||||
return FALSE;
|
||||
|
||||
offset = dest_clip_region->y - *dest_y;
|
||||
|
@ -85,34 +84,31 @@ void surface_blit_region_f(const SURFACE *src,
|
|||
int src_height,
|
||||
int dest_x,
|
||||
int dest_y) {
|
||||
byte *psrc, *pdest;
|
||||
int src_y_inc, dest_y_inc;
|
||||
int width;
|
||||
int lines_left;
|
||||
int num_dwords;
|
||||
const byte *psrc;
|
||||
byte *pdest;
|
||||
int lines;
|
||||
int src_y_inc = src->width - src_width;
|
||||
int dest_y_inc = dest->width - src_width;
|
||||
int width_4, width_remainder;
|
||||
|
||||
psrc = surface_pointer(src, src_x, src_y);
|
||||
src_y_inc = src->width;
|
||||
pdest = surface_pointer(dest, dest_x, dest_y);
|
||||
dest_y_inc = dest->width;
|
||||
width = src_width;
|
||||
lines_left = src_height;
|
||||
psrc = (const byte*)surface_pointer(src, src_x, src_y);
|
||||
pdest = (byte*)surface_pointer(dest, dest_x, dest_y);
|
||||
lines = src_height;
|
||||
|
||||
width_4 = src_width / 4;
|
||||
width_remainder = src_width & 3;
|
||||
|
||||
if (width_4 && !width_remainder) {
|
||||
// width is a multiple of 4 (no remainder)
|
||||
direct_blit_4(width_4, lines, pdest, psrc, dest_y_inc, src_y_inc);
|
||||
|
||||
} else if (width_4 && width_remainder) {
|
||||
// width is >= 4 and there is a remainder ( <= 3 )
|
||||
direct_blit_4r(width_4, lines, width_remainder, pdest, psrc, dest_y_inc, src_y_inc);
|
||||
|
||||
if (width % 4 == 0) {
|
||||
num_dwords = width / 4;
|
||||
while (lines_left) {
|
||||
REP_MOVSL(psrc, pdest, num_dwords);
|
||||
psrc += src_y_inc;
|
||||
pdest += dest_y_inc;
|
||||
--lines_left;
|
||||
}
|
||||
} else {
|
||||
while (lines_left) {
|
||||
REP_MOVSB(psrc, pdest, width);
|
||||
psrc += src_y_inc;
|
||||
pdest += dest_y_inc;
|
||||
--lines_left;
|
||||
}
|
||||
// width is <= 3
|
||||
direct_blit_r(width_remainder, lines, pdest, psrc, dest_y_inc, src_y_inc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,61 +140,49 @@ void surface_blit_sprite_region_f(const SURFACE *src,
|
|||
int src_height,
|
||||
int dest_x,
|
||||
int dest_y) {
|
||||
byte *psrc, *pdest;
|
||||
const byte *psrc;
|
||||
byte *pdest;
|
||||
byte pixel;
|
||||
int src_y_inc, dest_y_inc;
|
||||
int width;
|
||||
int width, width_4, width_8, width_remainder;
|
||||
int lines_left;
|
||||
int x;
|
||||
|
||||
psrc = surface_pointer(src, src_x, src_y);
|
||||
psrc = (const byte*)surface_pointer(src, src_x, src_y);
|
||||
src_y_inc = src->width;
|
||||
pdest = surface_pointer(dest, dest_x, dest_y);
|
||||
pdest = (byte*)surface_pointer(dest, dest_x, dest_y);
|
||||
dest_y_inc = dest->width;
|
||||
width = src_width;
|
||||
lines_left = src_height;
|
||||
|
||||
// based on benchmarking on a DX2-66, there is VERY significant
|
||||
// diminishing returns for loop unrolling beyond these sizes
|
||||
// (in fact, even the one for 8 is a very small gain over 4)
|
||||
if (width % 8 == 0) {
|
||||
while (lines_left) {
|
||||
for (x = 0; x < width; x += 8) {
|
||||
if ((pixel = psrc[x + 0])) pdest[x + 0] = pixel;
|
||||
if ((pixel = psrc[x + 1])) pdest[x + 1] = pixel;
|
||||
if ((pixel = psrc[x + 2])) pdest[x + 2] = pixel;
|
||||
if ((pixel = psrc[x + 3])) pdest[x + 3] = pixel;
|
||||
if ((pixel = psrc[x + 4])) pdest[x + 4] = pixel;
|
||||
if ((pixel = psrc[x + 5])) pdest[x + 5] = pixel;
|
||||
if ((pixel = psrc[x + 6])) pdest[x + 6] = pixel;
|
||||
if ((pixel = psrc[x + 7])) pdest[x + 7] = pixel;
|
||||
}
|
||||
psrc += src_y_inc;
|
||||
pdest += dest_y_inc;
|
||||
--lines_left;
|
||||
src_y_inc -= width;
|
||||
dest_y_inc -= width;
|
||||
|
||||
width_4 = width / 4;
|
||||
width_remainder = width & 3;
|
||||
|
||||
if (width_4 && !width_remainder) {
|
||||
if ((width_4 & 1) == 0) {
|
||||
// width is actually an even multiple of 8!
|
||||
direct_blit_sprite_8(width_4 / 2, lines_left, pdest, psrc, dest_y_inc, src_y_inc);
|
||||
} else {
|
||||
// width is a multiple of 4 (no remainder)
|
||||
direct_blit_sprite_4(width_4, lines_left, pdest, psrc, dest_y_inc, src_y_inc);
|
||||
}
|
||||
} else if (width % 4 == 0) {
|
||||
while (lines_left) {
|
||||
for (x = 0; x < width; x += 4) {
|
||||
if ((pixel = psrc[x + 0])) pdest[x + 0] = pixel;
|
||||
if ((pixel = psrc[x + 1])) pdest[x + 1] = pixel;
|
||||
if ((pixel = psrc[x + 2])) pdest[x + 2] = pixel;
|
||||
if ((pixel = psrc[x + 3])) pdest[x + 3] = pixel;
|
||||
}
|
||||
psrc += src_y_inc;
|
||||
pdest += dest_y_inc;
|
||||
--lines_left;
|
||||
|
||||
} else if (width_4 && width_remainder) {
|
||||
if ((width_4 & 1) == 0) {
|
||||
// width is _mostly_ made up of an even multiple of 8,
|
||||
// plus a small remainder
|
||||
direct_blit_sprite_8r(width_4 / 2, lines_left, pdest, psrc, width_remainder, dest_y_inc, src_y_inc);
|
||||
} else {
|
||||
// width is >= 4 and there is a remainder
|
||||
direct_blit_sprite_4r(width_4, lines_left, pdest, psrc, width_remainder, dest_y_inc, src_y_inc);
|
||||
}
|
||||
|
||||
} else {
|
||||
while (lines_left) {
|
||||
for (x = 0; x < width; ++x) {
|
||||
if ((pixel = psrc[x]))
|
||||
pdest[x] = pixel;
|
||||
}
|
||||
psrc += src_y_inc;
|
||||
pdest += dest_y_inc;
|
||||
--lines_left;
|
||||
}
|
||||
// width is <= 3
|
||||
direct_blit_sprite_r(width_remainder, lines_left, pdest, psrc, dest_y_inc, src_y_inc);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
#ifndef DGL_BLIT_H_INCLUDED
|
||||
#define DGL_BLIT_H_INCLUDED
|
||||
#ifndef DGL_DGLBLIT_H_INCLUDED
|
||||
#define DGL_DGLBLIT_H_INCLUDED
|
||||
|
||||
#include "gfx.h"
|
||||
#include "dglgfx.h"
|
||||
#include "dglutil.h"
|
||||
|
||||
void surface_blit_region(const SURFACE *src,
|
||||
SURFACE *dest,
|
||||
|
@ -21,8 +22,9 @@ void surface_blit_region_f(const SURFACE *src,
|
|||
int dest_x,
|
||||
int dest_y);
|
||||
|
||||
static inline void surface_blit(const SURFACE *src, SURFACE *dest, int x, int y);
|
||||
static inline void surface_blit_f(const SURFACE *src, SURFACE *dest, int x, int y);
|
||||
static void surface_blit(const SURFACE *src, SURFACE *dest, int x, int y);
|
||||
|
||||
static void surface_blit_f(const SURFACE *src, SURFACE *dest, int x, int y);
|
||||
|
||||
void surface_blit_sprite_region(const SURFACE *src,
|
||||
SURFACE *dest,
|
||||
|
@ -42,24 +44,34 @@ void surface_blit_sprite_region_f(const SURFACE *src,
|
|||
int dest_x,
|
||||
int dest_y);
|
||||
|
||||
static inline void surface_blit_sprite(const SURFACE *src, SURFACE *dest, int x, int y);
|
||||
static inline void surface_blit_sprite_f(const SURFACE *src, SURFACE *dest, int x, int y);
|
||||
void direct_blit_4(int width4, int lines, byte *dest, const byte *src, int dest_y_inc, int src_y_inc);
|
||||
void direct_blit_4r(int width4, int lines, int remainder, byte *dest, const byte *src, int dest_y_inc, int src_y_inc);
|
||||
void direct_blit_r(int width, int lines, byte *dest, const byte *src, int dest_y_inc, int src_y_inc);
|
||||
void direct_blit_sprite_4(int width4, int lines, byte *dest, const byte *src, int dest_y_inc, int src_y_inc);
|
||||
void direct_blit_sprite_4r(int width4, int lines, byte *dest, const byte *src, int remainder, int dest_y_inc, int src_y_inc);
|
||||
void direct_blit_sprite_r(int width, int lines, byte *dest, const byte *src, int dest_y_inc, int src_y_inc);
|
||||
void direct_blit_sprite_8(int width8, int lines, byte *dest, const byte *src, int dest_y_inc, int src_y_inc);
|
||||
void direct_blit_sprite_8r(int width8, int lines, byte *dest, const byte *src, int remainder, int dest_y_inc, int src_y_inc);
|
||||
|
||||
static void surface_blit_sprite(const SURFACE *src, SURFACE *dest, int x, int y);
|
||||
static void surface_blit_sprite_f(const SURFACE *src, SURFACE *dest, int x, int y);
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
static inline void surface_blit(const SURFACE *src, SURFACE *dest, int x, int y) {
|
||||
static void surface_blit(const SURFACE *src, SURFACE *dest, int x, int y) {
|
||||
surface_blit_region(src, dest, 0, 0, src->width, src->height, x, y);
|
||||
}
|
||||
|
||||
static inline void surface_blit_f(const SURFACE *src, SURFACE *dest, int x, int y) {
|
||||
|
||||
static void surface_blit_f(const SURFACE *src, SURFACE *dest, int x, int y) {
|
||||
surface_blit_region_f(src, dest, 0, 0, src->width, src->height, x, y);
|
||||
}
|
||||
|
||||
static inline void surface_blit_sprite(const SURFACE *src, SURFACE *dest, int x, int y) {
|
||||
static void surface_blit_sprite(const SURFACE *src, SURFACE *dest, int x, int y) {
|
||||
surface_blit_sprite_region(src, dest, 0, 0, src->width, src->height, x, y);
|
||||
}
|
||||
|
||||
static inline void surface_blit_sprite_f(const SURFACE *src, SURFACE *dest, int x, int y) {
|
||||
static void surface_blit_sprite_f(const SURFACE *src, SURFACE *dest, int x, int y) {
|
||||
surface_blit_sprite_region_f(src, dest, 0, 0, src->width, src->height, x, y);
|
||||
}
|
||||
|
535
DGLBLITA.ASM
Normal file
535
DGLBLITA.ASM
Normal file
|
@ -0,0 +1,535 @@
|
|||
ideal
|
||||
|
||||
p386
|
||||
p387
|
||||
model flat
|
||||
codeseg
|
||||
|
||||
locals
|
||||
|
||||
public direct_blit_4_
|
||||
public direct_blit_4r_
|
||||
public direct_blit_r_
|
||||
public direct_blit_sprite_4_
|
||||
public direct_blit_sprite_4r_
|
||||
public direct_blit_sprite_r_
|
||||
public direct_blit_sprite_8_
|
||||
public direct_blit_sprite_8r_
|
||||
|
||||
; direct_blit_4_
|
||||
; eax = width4
|
||||
; edx = lines
|
||||
; ebx = dest
|
||||
; ecx = src
|
||||
; ebp+8 = dest_y_inc
|
||||
; ebp+12 = src_y_inc
|
||||
proc direct_blit_4_ near
|
||||
arg @@dest_y_inc:dword, @@src_y_inc:dword
|
||||
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
push edi
|
||||
push esi
|
||||
|
||||
mov edi, ebx ; dest pixels
|
||||
mov esi, ecx ; source pixels
|
||||
|
||||
mov ebx, [@@src_y_inc]
|
||||
mov ebp, [@@dest_y_inc] ; WARNING: no stack/args access after this!
|
||||
|
||||
; eax = number of 4-pixel runs (dwords)
|
||||
; edx = line loop counter
|
||||
; ebx = src_y_inc
|
||||
; ebp = dest_y_inc
|
||||
|
||||
test edx, edx ; make sure there is >0 lines to draw
|
||||
jz @@done
|
||||
|
||||
@@draw_line:
|
||||
mov ecx, eax ; draw all 4-pixel runs (dwords)
|
||||
rep movsd
|
||||
|
||||
add esi, ebx ; move to next line
|
||||
add edi, ebp
|
||||
dec edx ; decrease line loop counter
|
||||
jnz @@draw_line ; keep going if there's more lines to draw
|
||||
|
||||
@@done:
|
||||
pop esi
|
||||
pop edi
|
||||
pop ebp
|
||||
ret 8
|
||||
|
||||
endp
|
||||
|
||||
; direct_blit_4r_
|
||||
; eax = width4
|
||||
; edx = lines
|
||||
; ebx = remainder
|
||||
; ecx = dest
|
||||
; ebp+8 = src
|
||||
; ebp+12 = dest_y_inc
|
||||
; ebp+16 = src_y_inc
|
||||
proc direct_blit_4r_ near
|
||||
arg @@src:dword, @@dest_y_inc:dword, @@src_y_inc:dword
|
||||
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
push edi
|
||||
push esi
|
||||
|
||||
mov edi, ecx ; dest pixels
|
||||
mov esi, [@@src] ; source pixels
|
||||
|
||||
; eax = number of 4-pixel runs (dwords)
|
||||
; ebx = remaining number of pixels
|
||||
; edx = line loop counter
|
||||
|
||||
test edx, edx ; make sure there is >0 lines to draw
|
||||
jz @@done
|
||||
|
||||
@@draw_line:
|
||||
mov ecx, eax ; draw all 4-pixel runs (dwords)
|
||||
rep movsd
|
||||
mov ecx, ebx ; draw remaining pixels ( <= 3 bytes )
|
||||
rep movsb
|
||||
|
||||
add esi, [@@src_y_inc] ; move to next line
|
||||
add edi, [@@dest_y_inc]
|
||||
dec edx ; decrease line loop counter
|
||||
jnz @@draw_line ; keep going if there's more lines to draw
|
||||
|
||||
@@done:
|
||||
pop esi
|
||||
pop edi
|
||||
pop ebp
|
||||
ret 12
|
||||
|
||||
endp
|
||||
|
||||
; direct_blit_r_
|
||||
; eax = width
|
||||
; edx = lines
|
||||
; ebx = dest
|
||||
; ecx = src
|
||||
; ebp+8 = dest_y_inc
|
||||
; ebp+12 = src_y_inc
|
||||
proc direct_blit_r_ near
|
||||
arg @@dest_y_inc:dword, @@src_y_inc:dword
|
||||
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
push edi
|
||||
push esi
|
||||
|
||||
mov edi, ebx ; dest pixels
|
||||
mov esi, ecx ; source pixels
|
||||
|
||||
; eax = number of pixels to draw (bytes)
|
||||
; edx = line loop counter
|
||||
|
||||
test edx, edx ; make sure there is >0 lines to draw
|
||||
jz @@done
|
||||
|
||||
@@draw_line:
|
||||
mov ecx, eax ; draw pixels (bytes)
|
||||
rep movsb
|
||||
|
||||
add esi, [@@src_y_inc] ; move to next line
|
||||
add edi, [@@dest_y_inc]
|
||||
dec edx ; decrease line loop counter
|
||||
jnz @@draw_line ; keep going if there's more lines to draw
|
||||
|
||||
@@done:
|
||||
pop esi
|
||||
pop edi
|
||||
pop ebp
|
||||
ret 8
|
||||
|
||||
endp
|
||||
|
||||
; direct_blit_sprite_4_
|
||||
; eax = width4
|
||||
; edx = lines
|
||||
; ebx = dest
|
||||
; ecx = src
|
||||
; ebp+8 = dest_y_inc
|
||||
; ebp+12 = src_y_inc
|
||||
proc direct_blit_sprite_4_ near
|
||||
arg @@dest_y_inc:dword, @@src_y_inc:dword
|
||||
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
push edi
|
||||
push esi
|
||||
|
||||
mov edi, ebx ; dest pixels
|
||||
mov esi, ecx ; source pixels
|
||||
|
||||
; eax = number of 4-pixel runs (dwords)
|
||||
; edx = line loop counter
|
||||
|
||||
test edx, edx ; make sure there is >0 lines to be drawn
|
||||
jz @@done
|
||||
|
||||
@@draw_line:
|
||||
|
||||
@@start_4_run:
|
||||
mov ecx, eax ; ecx = counter of 4-pixel runs left to draw
|
||||
@@draw_px_0:
|
||||
mov bx, [esi+0] ; load src pixel
|
||||
test bl, bl
|
||||
jz @@draw_px_1 ; if it is color 0, skip it
|
||||
mov [edi+0], bl ; otherwise, draw it onto dest
|
||||
@@draw_px_1:
|
||||
test bh, bh
|
||||
jz @@draw_px_2
|
||||
mov [edi+1], bh
|
||||
@@draw_px_2:
|
||||
mov bx, [esi+2]
|
||||
test bl, bl
|
||||
jz @@draw_px_3
|
||||
mov [edi+2], bl
|
||||
@@draw_px_3:
|
||||
test bh, bh
|
||||
jz @@end_4_run
|
||||
mov [edi+3], bh
|
||||
@@end_4_run:
|
||||
add esi, 4 ; move src and dest up 4 pixels
|
||||
add edi, 4
|
||||
dec ecx ; decrease 4-pixel run loop counter
|
||||
jnz @@draw_px_0 ; if there are still more runs, draw them
|
||||
|
||||
@@end_line:
|
||||
add esi, [@@src_y_inc] ; move src and dest to start of next line
|
||||
add edi, [@@dest_y_inc]
|
||||
dec edx ; decrease line loop counter
|
||||
jnz @@draw_line ; keep going if there's more lines to draw
|
||||
|
||||
@@done:
|
||||
pop esi
|
||||
pop edi
|
||||
pop ebp
|
||||
ret 8
|
||||
|
||||
endp
|
||||
|
||||
; direct_blit_sprite_4r_
|
||||
; eax = width4
|
||||
; edx = lines
|
||||
; ebx = dest
|
||||
; ecx = src
|
||||
; ebp+8 = remainder
|
||||
; ebp+12 = dest_y_inc
|
||||
; ebp+16 = src_y_inc
|
||||
proc direct_blit_sprite_4r_ near
|
||||
arg @@remainder:dword, @@dest_y_inc:dword, @@src_y_inc:dword
|
||||
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
push edi
|
||||
push esi
|
||||
|
||||
mov edi, ebx ; dest pixels
|
||||
mov esi, ecx ; source pixels
|
||||
|
||||
; eax = number of 4-pixel runs (dwords)
|
||||
; edx = line loop counter
|
||||
|
||||
test edx, edx ; make sure there is >0 lines to be drawn
|
||||
jz @@done
|
||||
|
||||
@@draw_line:
|
||||
|
||||
@@start_4_run: ; draw 4-pixel runs first
|
||||
mov ecx, eax ; ecx = counter of 4-pixel runs left to draw
|
||||
@@draw_px_0:
|
||||
mov bx, [esi+0] ; load src pixel
|
||||
test bl, bl
|
||||
jz @@draw_px_1 ; if it is color 0, skip it
|
||||
mov [edi+0], bl ; otherwise, draw it onto dest
|
||||
@@draw_px_1:
|
||||
test bh, bh
|
||||
jz @@draw_px_2
|
||||
mov [edi+1], bh
|
||||
@@draw_px_2:
|
||||
mov bx, [esi+2]
|
||||
test bl, bl
|
||||
jz @@draw_px_3
|
||||
mov [edi+2], bl
|
||||
@@draw_px_3:
|
||||
test bh, bh
|
||||
jz @@end_4_run
|
||||
mov [edi+3], bh
|
||||
@@end_4_run:
|
||||
add esi, 4 ; move src and dest up 4 pixels
|
||||
add edi, 4
|
||||
dec ecx ; decrease 4-pixel run loop counter
|
||||
jnz @@draw_px_0 ; if there are still more runs, draw them
|
||||
|
||||
@@start_remainder_run: ; now draw remaining pixels ( <= 3 pixels )
|
||||
mov ecx, [@@remainder] ; ecx = counter of remaining pixels
|
||||
|
||||
@@draw_pixel:
|
||||
mov bl, [esi] ; load pixel
|
||||
inc esi
|
||||
test bl, bl ; if zero, skip to next pixel
|
||||
jz @@end_pixel
|
||||
mov [edi], bl ; else, draw pixel
|
||||
@@end_pixel:
|
||||
inc edi
|
||||
dec ecx
|
||||
jnz @@draw_pixel ; keep drawing pixels while there's still more
|
||||
|
||||
@@end_line:
|
||||
add esi, [@@src_y_inc] ; move src and dest to start of next line
|
||||
add edi, [@@dest_y_inc]
|
||||
dec edx ; decrease line loop counter
|
||||
jnz @@draw_line ; keep going if there's more lines to draw
|
||||
|
||||
@@done:
|
||||
pop esi
|
||||
pop edi
|
||||
pop ebp
|
||||
ret 12
|
||||
|
||||
endp
|
||||
|
||||
; direct_blit_sprite_r_
|
||||
; eax = width
|
||||
; edx = lines
|
||||
; ebx = dest
|
||||
; ecx = src
|
||||
; ebp+8 = dest_y_inc
|
||||
; ebp+12 = src_y_inc
|
||||
proc direct_blit_sprite_r_ near
|
||||
arg @@dest_y_inc:dword, @@src_y_inc:dword
|
||||
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
push edi
|
||||
push esi
|
||||
|
||||
mov edi, ebx ; dest pixels
|
||||
mov esi, ecx ; source pixels
|
||||
|
||||
; eax = number of 4-pixel runs (dwords)
|
||||
; edx = line loop counter
|
||||
|
||||
test edx, edx ; make sure there is >0 lines to be drawn
|
||||
jz @@done
|
||||
|
||||
@@draw_line:
|
||||
mov ecx, eax ; ecx = counter of remaining pixels
|
||||
|
||||
@@draw_pixel:
|
||||
mov bl, [esi] ; load pixel
|
||||
inc esi
|
||||
test bl, bl ; if zero, skip to next pixel
|
||||
jz @@end_pixel
|
||||
mov [edi], bl ; else, draw pixel
|
||||
@@end_pixel:
|
||||
inc edi
|
||||
dec ecx
|
||||
jnz @@draw_pixel ; loop while there's still pixels left
|
||||
|
||||
@@end_line:
|
||||
add esi, [@@src_y_inc] ; move src and dest to start of next line
|
||||
add edi, [@@dest_y_inc]
|
||||
dec edx ; decrease line loop counter
|
||||
jnz @@draw_line ; keep going if there's more lines to draw
|
||||
|
||||
@@done:
|
||||
pop esi
|
||||
pop edi
|
||||
pop ebp
|
||||
ret 8
|
||||
|
||||
endp
|
||||
|
||||
; direct_blit_sprite_8_
|
||||
; eax = width8
|
||||
; edx = lines
|
||||
; ebx = dest
|
||||
; ecx = src
|
||||
; ebp+8 = dest_y_inc
|
||||
; ebp+12 = src_y_inc
|
||||
proc direct_blit_sprite_8_ near
|
||||
arg @@dest_y_inc:dword, @@src_y_inc:dword
|
||||
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
push edi
|
||||
push esi
|
||||
|
||||
mov edi, ebx ; dest pixels
|
||||
mov esi, ecx ; source pixels
|
||||
mov ebp, eax ; WARNING: no named local access after this!
|
||||
|
||||
; ebp = number of 8-pixel runs
|
||||
; edx = line loop counter
|
||||
; ebx = pixel data
|
||||
; eax = pixel data
|
||||
|
||||
test edx, edx ; make sure there is >0 lines to be drawn
|
||||
jz @@done
|
||||
|
||||
@@draw_line:
|
||||
mov ecx, ebp ; ecx = counter of 8-pixel runs left to draw
|
||||
@@draw_px_0:
|
||||
mov bx, [esi+0] ; load src pixel
|
||||
mov ax, [esi+2]
|
||||
test bl, bl
|
||||
jz @@draw_px_1 ; if it is color 0, skip it
|
||||
mov [edi+0], bl ; otherwise, draw it onto dest
|
||||
@@draw_px_1:
|
||||
test al, al
|
||||
jz @@draw_px_2
|
||||
mov [edi+2], al
|
||||
@@draw_px_2:
|
||||
test bh, bh
|
||||
jz @@draw_px_3
|
||||
mov [edi+1], bh
|
||||
@@draw_px_3:
|
||||
test ah, ah
|
||||
jz @@draw_px_4
|
||||
mov [edi+3], ah
|
||||
@@draw_px_4:
|
||||
mov bx, [esi+4]
|
||||
mov ax, [esi+6]
|
||||
test bl, bl
|
||||
jz @@draw_px_5
|
||||
mov [edi+4], bl
|
||||
@@draw_px_5:
|
||||
test al, al
|
||||
jz @@draw_px_6
|
||||
mov [edi+6], al
|
||||
@@draw_px_6:
|
||||
test bh, bh
|
||||
jz @@draw_px_7
|
||||
mov [edi+5], bh
|
||||
@@draw_px_7:
|
||||
test ah, ah
|
||||
jz @@end_8_run
|
||||
mov [edi+7], ah
|
||||
@@end_8_run:
|
||||
add esi, 8 ; move src and dest up 8 pixels
|
||||
add edi, 8
|
||||
dec ecx ; decrease 8-pixel run loop counter
|
||||
jnz @@draw_px_0 ; if there are still more runs, draw them
|
||||
|
||||
@@end_line:
|
||||
add esi, [esp+20] ; move src and dest to start of next line
|
||||
add edi, [esp+16]
|
||||
dec edx ; decrease line loop counter
|
||||
jnz @@draw_line ; keep going if there's more lines to draw
|
||||
|
||||
@@done:
|
||||
pop esi
|
||||
pop edi
|
||||
pop ebp
|
||||
ret 8
|
||||
|
||||
endp
|
||||
|
||||
; direct_blit_sprite_8r_
|
||||
; eax = width8
|
||||
; edx = lines
|
||||
; ebx = dest
|
||||
; ecx = src
|
||||
; ebp+8 = remainder
|
||||
; ebp+12 = dest_y_inc
|
||||
; ebp+16 = src_y_inc
|
||||
proc direct_blit_sprite_8r_ near
|
||||
arg @@remainder:dword, @@dest_y_inc:dword, @@src_y_inc:dword
|
||||
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
push edi
|
||||
push esi
|
||||
|
||||
mov edi, ebx ; dest pixels
|
||||
mov esi, ecx ; source pixels
|
||||
|
||||
; eax = number of 8-pixel runs
|
||||
; edx = line loop counter
|
||||
|
||||
test edx, edx ; make sure there is >0 lines to be drawn
|
||||
jz @@done
|
||||
|
||||
@@draw_line:
|
||||
|
||||
@@start_8_run: ; draw 8-pixel runs first
|
||||
mov ecx, eax ; ecx = counter of 8-pixel runs left to draw
|
||||
@@draw_px_0:
|
||||
mov bx, [esi+0] ; load src pixel
|
||||
test bl, bl
|
||||
jz @@draw_px_1 ; if it is color 0, skip it
|
||||
mov [edi+0], bl ; otherwise, draw it onto dest
|
||||
@@draw_px_1:
|
||||
test bh, bh
|
||||
jz @@draw_px_2
|
||||
mov [edi+1], bh
|
||||
@@draw_px_2:
|
||||
mov bx, [esi+2]
|
||||
test bl, bl
|
||||
jz @@draw_px_3
|
||||
mov [edi+2], bl
|
||||
@@draw_px_3:
|
||||
test bh, bh
|
||||
jz @@draw_px_4
|
||||
mov [edi+3], bh
|
||||
@@draw_px_4:
|
||||
mov bx, [esi+4]
|
||||
test bl, bl
|
||||
jz @@draw_px_5
|
||||
mov [edi+4], bl
|
||||
@@draw_px_5:
|
||||
test bh, bh
|
||||
jz @@draw_px_6
|
||||
mov [edi+5], bh
|
||||
@@draw_px_6:
|
||||
mov bx, [esi+6]
|
||||
test bl, bl
|
||||
jz @@draw_px_7
|
||||
mov [edi+6], bl
|
||||
@@draw_px_7:
|
||||
test bh, bh
|
||||
jz @@end_8_run
|
||||
mov [edi+7], bh
|
||||
@@end_8_run:
|
||||
add esi, 8 ; move src and dest up 8 pixels
|
||||
add edi, 8
|
||||
dec ecx ; decrease 8-pixel run loop counter
|
||||
jnz @@draw_px_0 ; if there are still more runs, draw them
|
||||
|
||||
@@start_remainder_run: ; now draw remaining pixels ( <= 7 pixels )
|
||||
mov ecx, [@@remainder] ; ecx = counter of remaining pixels
|
||||
|
||||
@@draw_pixel:
|
||||
mov bl, [esi] ; load pixel
|
||||
inc esi
|
||||
test bl, bl ; if zero, skip to next pixel
|
||||
jz @@end_pixel
|
||||
mov [edi], bl ; else, draw pixel
|
||||
@@end_pixel:
|
||||
inc edi
|
||||
dec ecx
|
||||
jnz @@draw_pixel ; loop while there's still pixels left
|
||||
|
||||
@@end_line:
|
||||
add esi, [@@src_y_inc] ; move src and dest to start of next line
|
||||
add edi, [@@dest_y_inc]
|
||||
dec edx ; decrease line loop counter
|
||||
jnz @@draw_line ; keep going if there's more lines to draw
|
||||
|
||||
@@done:
|
||||
pop esi
|
||||
pop edi
|
||||
pop ebp
|
||||
ret 12
|
||||
|
||||
endp
|
||||
|
||||
end
|
||||
|
|
@ -1,15 +1,15 @@
|
|||
#include "clipping.h"
|
||||
#include "common.h"
|
||||
#include "mathext.h"
|
||||
#include "dglclip.h"
|
||||
#include "dglcmn.h"
|
||||
#include "dglmath.h"
|
||||
|
||||
static inline boolean is_in_bounds(int clip_x,
|
||||
int clip_y,
|
||||
int clip_right,
|
||||
int clip_bottom,
|
||||
int x1,
|
||||
int y1,
|
||||
int x2,
|
||||
int y2) {
|
||||
static boolean is_in_bounds(int clip_x,
|
||||
int clip_y,
|
||||
int clip_right,
|
||||
int clip_bottom,
|
||||
int x1,
|
||||
int y1,
|
||||
int x2,
|
||||
int y2) {
|
||||
if (y1 < clip_y && y2 < clip_y)
|
||||
return FALSE;
|
||||
if (y1 > clip_bottom && y2 > clip_bottom)
|
|
@ -1,8 +1,8 @@
|
|||
#ifndef DGL_CLIPPING_H_INCLUDED
|
||||
#define DGL_CLIPPING_H_INCLUDED
|
||||
#ifndef DGL_DGLCLIP_H_INCLUDED
|
||||
#define DGL_DGLCLIP_H_INCLUDED
|
||||
|
||||
#include "common.h"
|
||||
#include "rect.h"
|
||||
#include "dglcmn.h"
|
||||
#include "dglrect.h"
|
||||
|
||||
/*
|
||||
* Determines if the given point lies within the clipping region.
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef DGL_COMMON_H_INCLUDED
|
||||
#define DGL_COMMON_H_INCLUDED
|
||||
#ifndef DGL_DGLCMN_H_INCLUDED
|
||||
#define DGL_DGLCMN_H_INCLUDED
|
||||
|
||||
typedef int boolean;
|
||||
|
||||
|
@ -27,7 +27,7 @@ typedef unsigned int uint;
|
|||
#define BIT_6 0x40
|
||||
#define BIT_7 0x80
|
||||
|
||||
#define BIT_ISSET(bit, x) ((x) & (bit) != 0)
|
||||
#define BIT_ISSET(bit, x) ((x) & (bit))
|
||||
#define BIT_SET(bit, x) ((x) |= (bit))
|
||||
#define BIT_CLEAR(bit, x) ((x) &= ~(bit))
|
||||
#define BIT_TOGGLE(bit, x) ((x) ^= (bit))
|
|
@ -1,27 +1,36 @@
|
|||
#include "draw.h"
|
||||
#include "gfx.h"
|
||||
#include "mathext.h"
|
||||
#include "util.h"
|
||||
#include "internal.h"
|
||||
#include "dgldraw.h"
|
||||
#include "dglgfx.h"
|
||||
#include "dglmath.h"
|
||||
#include "dglutil.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
static char printf_buffer[1024];
|
||||
|
||||
void surface_hline_f(SURFACE *surface, int x1, int x2, int y, int color) {
|
||||
byte *p = surface_pointer(surface, x1, y);
|
||||
memset(p, color, x2 - x1 + 1);
|
||||
mem_fill(p, color, (x2 - x1 + 1));
|
||||
}
|
||||
|
||||
void surface_vline_f(SURFACE *surface, int x, int y1, int y2, int color) {
|
||||
byte *p = surface_pointer(surface, x, y1);
|
||||
int line_inc = surface->width;
|
||||
int y;
|
||||
int lines_left = y2 - y1 + 1;
|
||||
|
||||
for (y = y1; y <= y2; ++y, p += line_inc) {
|
||||
*p = (byte)color;
|
||||
}
|
||||
extern void draw_line(byte *dest, int color, int line_inc, int lines_left);
|
||||
#pragma aux draw_line = \
|
||||
" test ecx, ecx" \
|
||||
" jz done" \
|
||||
"draw:" \
|
||||
" mov [edx], al" \
|
||||
" add edx, ebx" \
|
||||
" dec ecx" \
|
||||
" jnz draw" \
|
||||
"done:" \
|
||||
parm [edx] [eax] [ebx] [ecx];
|
||||
draw_line(p, color, line_inc, lines_left);
|
||||
}
|
||||
|
||||
void surface_line(SURFACE *surface, int x1, int y1, int x2, int y2, int color) {
|
||||
|
@ -152,77 +161,95 @@ void surface_line_f(SURFACE *surface, int x1, int y1, int x2, int y2, int color)
|
|||
}
|
||||
}
|
||||
|
||||
extern void draw_both_vert_lines(byte *left, byte *right, int color, int y_inc, int height);
|
||||
#pragma aux draw_both_vert_lines = \
|
||||
" inc ecx" \
|
||||
"draw:" \
|
||||
" mov [edi], al" \
|
||||
" mov [esi], al" \
|
||||
" add edi, edx" \
|
||||
" add esi, edx" \
|
||||
" dec ecx" \
|
||||
" jnz draw" \
|
||||
"done:" \
|
||||
parm [edi] [esi] [eax] [edx] [ecx];
|
||||
|
||||
extern void draw_vert_line(byte *dest, int color, int y_inc, int height);
|
||||
#pragma aux draw_vert_line = \
|
||||
" inc ecx" \
|
||||
"draw:" \
|
||||
" mov [edi], al" \
|
||||
" add edi, edx" \
|
||||
" dec ecx" \
|
||||
" jnz draw" \
|
||||
"done:" \
|
||||
parm [edi] [eax] [edx] [ecx];
|
||||
|
||||
void surface_rect(SURFACE *surface, int x1, int y1, int x2, int y2, int color) {
|
||||
byte *p1, *p2;
|
||||
int width;
|
||||
int y;
|
||||
int y_inc = surface->width;
|
||||
int clipped_x1 = x1;
|
||||
int clipped_y1 = y1;
|
||||
int clipped_x2 = x2;
|
||||
int clipped_y2 = y2;
|
||||
int clip_right = rect_right(&surface->clip_region);
|
||||
int clip_bottom = rect_bottom(&surface->clip_region);
|
||||
RECT clipped;
|
||||
int clipped_x2, clipped_y2;
|
||||
|
||||
if (x1 < surface->clip_region.x)
|
||||
clipped_x1 = surface->clip_region.x;
|
||||
if (x2 > clip_right)
|
||||
clipped_x2 = clip_right;
|
||||
if (x2 < x1)
|
||||
SWAP(int, x1, x2);
|
||||
if (y2 < y1)
|
||||
SWAP(int, y1, y2);
|
||||
|
||||
width = clipped_x2 - clipped_x1 + 1;
|
||||
clipped.x = x1;
|
||||
clipped.y = y1;
|
||||
clipped.width = x2 - x1 + 1;
|
||||
clipped.height = y2 - y1 + 1;
|
||||
|
||||
if (!clip_to_region(&surface->clip_region, &clipped))
|
||||
return;
|
||||
|
||||
clipped_x2 = clipped.x + clipped.width - 1;
|
||||
clipped_y2 = clipped.y + clipped.height - 1;
|
||||
color = fill32(color);
|
||||
|
||||
// top line, only if y1 was within bounds
|
||||
if (y1 < surface->clip_region.y)
|
||||
clipped_y1 = surface->clip_region.y;
|
||||
else
|
||||
memset(surface_pointer(surface, clipped_x1, clipped_y1), color, width);
|
||||
if (y1 == clipped.y) {
|
||||
byte *p = surface_pointer(surface, clipped.x, clipped.y);
|
||||
mem_fill32(p, color, clipped.width);
|
||||
}
|
||||
|
||||
// bottom line, only if y2 was within bounds
|
||||
if (y2 > clip_bottom)
|
||||
clipped_y2 = clip_bottom;
|
||||
else
|
||||
memset(surface_pointer(surface, clipped_x1, clipped_y2), color, width);
|
||||
if (y2 == clipped_y2) {
|
||||
byte *p = surface_pointer(surface, clipped.x, clipped_y2);
|
||||
mem_fill32(p, color, clipped.width);
|
||||
}
|
||||
|
||||
// draw both left and right lines if neither x1 nor x2 were clipped
|
||||
if (x1 == clipped_x1 && x2 == clipped_x2) {
|
||||
p1 = surface_pointer(surface, x1, y1);
|
||||
p2 = surface_pointer(surface, x2, y1);
|
||||
for (y = y1; y <= y2; ++y, p1 += y_inc, p2 += y_inc) {
|
||||
*p1 = (byte)color;
|
||||
*p2 = (byte)color;
|
||||
}
|
||||
if (x1 == clipped.x && x2 == clipped_x2) {
|
||||
byte *p1 = surface_pointer(surface, clipped.x, clipped.y);
|
||||
byte *p2 = surface_pointer(surface, clipped_x2, clipped.y);
|
||||
draw_both_vert_lines(p1, p2, color, surface->width, clipped.height - 1);
|
||||
|
||||
// draw left line if x1 was not clipped
|
||||
} else if (x1 == clipped_x1) {
|
||||
p1 = surface_pointer(surface, x1, y1);
|
||||
for (y = y1; y <= y2; ++y, p1 += y_inc)
|
||||
*p1 = (byte)color;
|
||||
} else if (x1 == clipped.x) {
|
||||
byte *p = surface_pointer(surface, clipped.x, clipped.y);
|
||||
draw_vert_line(p, color, surface->width, clipped.height - 1);
|
||||
|
||||
// draw right line if x2 was not clipped
|
||||
} else if (x2 == clipped_x2) {
|
||||
p1 = surface_pointer(surface, x2, y1);
|
||||
for (y = y1; y <= y2; ++y, p1 += y_inc)
|
||||
*p1 = (byte)color;
|
||||
byte *p = surface_pointer(surface, clipped_x2, clipped.y);
|
||||
draw_vert_line(p, color, surface->width, clipped.height - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void surface_rect_f(SURFACE *surface, int x1, int y1, int x2, int y2, int color) {
|
||||
byte *p1, *p2;
|
||||
byte *p;
|
||||
byte *p1;
|
||||
byte *p2;
|
||||
int width = x2 - x1 + 1;
|
||||
int y;
|
||||
int lines_left = y2 - y1;
|
||||
int y_inc = surface->width;
|
||||
|
||||
p1 = surface_pointer(surface, x1, y1);
|
||||
p2 = surface_pointer(surface, x1, y2);
|
||||
memset(p1, color, width);
|
||||
memset(p2, color, width);
|
||||
p = surface_pointer(surface, x1, y1);
|
||||
|
||||
p1 = surface_pointer(surface, x1, y1);
|
||||
p2 = surface_pointer(surface, x2, y1);
|
||||
for (y = y1; y <= y2; ++y, p1 += y_inc, p2 += y_inc) {
|
||||
*p1 = (byte)color;
|
||||
*p2 = (byte)color;
|
||||
}
|
||||
p1 = p;
|
||||
p2 = p + width - 1;
|
||||
|
||||
direct_rect_f(color, width, y_inc, lines_left, p1, p2);
|
||||
}
|
||||
|
||||
void surface_filled_rect(SURFACE *surface,
|
||||
|
@ -234,6 +261,11 @@ void surface_filled_rect(SURFACE *surface,
|
|||
if (!clamp_to_region(&surface->clip_region, &x1, &y1, &x2, &y2))
|
||||
return;
|
||||
|
||||
if (x2 < x1)
|
||||
SWAP(int, x1, x2);
|
||||
if (y2 < y1)
|
||||
SWAP(int, y1, y2);
|
||||
|
||||
surface_filled_rect_f(surface, x1, y1, x2, y2, color);
|
||||
}
|
||||
|
||||
|
@ -245,14 +277,12 @@ void surface_filled_rect_f(SURFACE *surface,
|
|||
int color) {
|
||||
byte *p;
|
||||
int width = x2 - x1 + 1;
|
||||
int y;
|
||||
int y_inc = surface->width;
|
||||
int lines_left = y2 - y1 + 1;
|
||||
|
||||
p = surface_pointer(surface, x1, y1);
|
||||
for (y = y1; y <= y2; ++y) {
|
||||
memset(p, (byte)color, width);
|
||||
p += y_inc;
|
||||
}
|
||||
|
||||
direct_filled_rect_f(color, y_inc, width, lines_left, p);
|
||||
}
|
||||
|
||||
#define CHAR_WIDTH 8
|
||||
|
@ -262,12 +292,12 @@ void surface_filled_rect_f(SURFACE *surface,
|
|||
|
||||
// dest_x, dest_y - original unclipped render x,y coords
|
||||
// dest_clipped - clipped destination render region
|
||||
static inline void print_char(SURFACE *surface,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
const RECT *dest_clipped,
|
||||
int color,
|
||||
char c) {
|
||||
static void print_char(SURFACE *surface,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
const RECT *dest_clipped,
|
||||
int color,
|
||||
char c) {
|
||||
byte *p;
|
||||
byte *rom_char;
|
||||
char char_line_bits;
|
||||
|
@ -277,7 +307,7 @@ static inline void print_char(SURFACE *surface,
|
|||
int y_inc = surface->width;
|
||||
|
||||
p = surface_pointer(surface, dest_clipped->x, dest_clipped->y);
|
||||
rom_char = map_dos_memory(0xffa6e) + (c * CHAR_HEIGHT);
|
||||
rom_char = ((byte*)0xffa6e) + (c * CHAR_HEIGHT);
|
||||
|
||||
// get offset x,y to start rendering char from (will be in range 0-7)
|
||||
offset_x = dest_clipped->x - dest_x;
|
||||
|
@ -298,12 +328,12 @@ static inline void print_char(SURFACE *surface,
|
|||
}
|
||||
}
|
||||
|
||||
static inline void print_text(SURFACE *surface,
|
||||
int x,
|
||||
int y,
|
||||
int color,
|
||||
boolean clip,
|
||||
const char *text) {
|
||||
static void print_text(SURFACE *surface,
|
||||
int x,
|
||||
int y,
|
||||
int color,
|
||||
boolean clip,
|
||||
const char *text) {
|
||||
const char *c;
|
||||
RECT r;
|
||||
RECT draw_r;
|
||||
|
@ -311,12 +341,17 @@ static inline void print_text(SURFACE *surface,
|
|||
r = rect(x, y, CHAR_WIDTH, CHAR_HEIGHT);
|
||||
|
||||
for (c = text; *c; ++c) {
|
||||
if (*c == '\n') {
|
||||
switch (*c) {
|
||||
case '\n':
|
||||
r.x = x;
|
||||
r.y += r.height;
|
||||
} else if (*c == ' ') {
|
||||
break;
|
||||
case ' ':
|
||||
r.x += r.width;
|
||||
} else {
|
||||
break;
|
||||
case '\r':
|
||||
break;
|
||||
default:
|
||||
if (clip) {
|
||||
draw_r = r;
|
||||
if (clip_to_region(&surface->clip_region, &draw_r))
|
|
@ -1,18 +1,18 @@
|
|||
#ifndef DGL_DRAW_H_INCLUDED
|
||||
#define DGL_DRAW_H_INCLUDED
|
||||
#ifndef DGL_DGLDRAW_H_INCLUDED
|
||||
#define DGL_DGLDRAW_H_INCLUDED
|
||||
|
||||
#include "gfx.h"
|
||||
#include "clipping.h"
|
||||
#include "util.h"
|
||||
#include "dglgfx.h"
|
||||
#include "dglclip.h"
|
||||
#include "dglutil.h"
|
||||
|
||||
static inline void surface_pset(SURFACE *surface, int x, int y, int color);
|
||||
static inline void surface_pset_f(SURFACE *surface, int x, int y, int color);
|
||||
static inline int surface_point(const SURFACE *surface, int x, int y);
|
||||
static inline int surface_point_f(const SURFACE *surface, int x, int y);
|
||||
static void surface_pset(SURFACE *surface, int x, int y, int color);
|
||||
static void surface_pset_f(SURFACE *surface, int x, int y, int color);
|
||||
static int surface_point(const SURFACE *surface, int x, int y);
|
||||
static int surface_point_f(const SURFACE *surface, int x, int y);
|
||||
|
||||
static inline void surface_hline(SURFACE *surface, int x1, int x2, int y, int color);
|
||||
static void surface_hline(SURFACE *surface, int x1, int x2, int y, int color);
|
||||
void surface_hline_f(SURFACE *surface, int x1, int x2, int y, int color);
|
||||
static inline void surface_vline(SURFACE *surface, int x, int y1, int y2, int color);
|
||||
static void surface_vline(SURFACE *surface, int x, int y1, int y2, int color);
|
||||
void surface_vline_f(SURFACE *surface, int x, int y1, int y2, int color);
|
||||
void surface_line(SURFACE *surface, int x1, int y1, int x2, int y2, int color);
|
||||
void surface_line_f(SURFACE *surface, int x1, int y1, int x2, int y2, int color);
|
||||
|
@ -27,37 +27,41 @@ void surface_text_f(SURFACE *surface, int x, int y, int color, const char *text)
|
|||
void surface_printf(SURFACE *surface, int x, int y, int color, const char *format, ...);
|
||||
void surface_printf_f(SURFACE *surface, int x, int y, int color, const char *format, ...);
|
||||
|
||||
void direct_rect_f(int color, int width, int y_inc, int lines, byte *p1, byte *p2);
|
||||
void direct_filled_rect_f(int color, int y_inc, int width, int lines, byte *dest);
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
static inline void surface_pset(SURFACE *surface, int x, int y, int color) {
|
||||
static void surface_pset(SURFACE *surface, int x, int y, int color) {
|
||||
if (is_point_in_bounds(&surface->clip_region, x, y))
|
||||
surface_pset_f(surface, x, y, color);
|
||||
}
|
||||
|
||||
static inline void surface_pset_f(SURFACE *surface, int x, int y, int color) {
|
||||
*(surface_pointer(surface, x, y)) = (byte)color;
|
||||
static void surface_pset_f(SURFACE *surface, int x, int y, int color) {
|
||||
int offset = surface_offset(surface, x, y);
|
||||
surface->pixels[offset] = color;
|
||||
}
|
||||
|
||||
static inline int surface_point(const SURFACE *surface, int x, int y) {
|
||||
static int surface_point(const SURFACE *surface, int x, int y) {
|
||||
if (is_point_in_bounds(&surface->clip_region, x, y))
|
||||
return surface_point_f(surface, x, y);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int surface_point_f(const SURFACE *surface, int x, int y) {
|
||||
return (int)*(surface_pointer(surface, x, y));
|
||||
static int surface_point_f(const SURFACE *surface, int x, int y) {
|
||||
int offset = surface_offset(surface, x, y);
|
||||
return surface->pixels[offset];
|
||||
}
|
||||
|
||||
static inline void surface_hline(SURFACE *surface, int x1, int x2, int y, int color) {
|
||||
static void surface_hline(SURFACE *surface, int x1, int x2, int y, int color) {
|
||||
if (x2 < x1)
|
||||
SWAP(int, x1, x2);
|
||||
if (clamp_to_region(&surface->clip_region, &x1, &y, &x2, &y))
|
||||
surface_hline_f(surface, x1, x2, y, color);
|
||||
}
|
||||
|
||||
static inline void surface_vline(SURFACE *surface, int x, int y1, int y2, int color) {
|
||||
static void surface_vline(SURFACE *surface, int x, int y1, int y2, int color) {
|
||||
if (y2 < y1)
|
||||
SWAP(int, y1, y2);
|
||||
if (clamp_to_region(&surface->clip_region, &x, &y1, &x, &y2))
|
159
DGLDRAWA.ASM
Normal file
159
DGLDRAWA.ASM
Normal file
|
@ -0,0 +1,159 @@
|
|||
ideal
|
||||
|
||||
p386
|
||||
p387
|
||||
model flat
|
||||
codeseg
|
||||
|
||||
locals
|
||||
|
||||
public direct_rect_f_
|
||||
public direct_filled_rect_f_
|
||||
|
||||
|
||||
; direct_rect_f_
|
||||
; eax = color
|
||||
; edx = width
|
||||
; ebx = y_inc
|
||||
; ecx = lines
|
||||
; ebp+8 = p1
|
||||
; ebp+12 = p2
|
||||
proc direct_rect_f_ near
|
||||
arg @@p1:dword, @@p2:dword
|
||||
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
push edi
|
||||
push esi
|
||||
|
||||
mov ah, al ; spread color byte out over all 32-bits
|
||||
shl eax, 8 ; so 4 pixels can be written horizontally
|
||||
mov al, ah ; later on
|
||||
shl eax, 8
|
||||
mov al, ah
|
||||
|
||||
mov edi, [@@p1] ; left edge
|
||||
mov esi, [@@p2] ; right edge
|
||||
|
||||
; al = color to draw
|
||||
; ebx = amount to inc both pointers by to move down 1 line
|
||||
; ecx = number of lines vertically to draw
|
||||
|
||||
test ecx, ecx
|
||||
jz @@draw_horiz1
|
||||
|
||||
@@draw_vert:
|
||||
mov [edi], al
|
||||
mov [esi], al
|
||||
add edi, ebx
|
||||
add esi, ebx
|
||||
dec ecx
|
||||
jnz @@draw_vert
|
||||
|
||||
@@draw_horiz1:
|
||||
; edi is currently at (x1,y2) after previous drawing. this is the
|
||||
; correct location to draw the bottom horizontal line, so we will
|
||||
; draw it now
|
||||
mov ecx, edx ; edx = number of pixels to draw
|
||||
mov ebx, ecx ; ecx = number of dwords to draw
|
||||
shr ecx, 2 ; ebx = remaining number of pixels ( <= 3 )
|
||||
and ebx, 3
|
||||
|
||||
rep stosd ; draw the line
|
||||
mov ecx, ebx
|
||||
rep stosb
|
||||
|
||||
@@draw_horiz2:
|
||||
; now draw top horizontal line
|
||||
mov edi, [@@p1] ; reset edi to top horizontal line start position
|
||||
mov ecx, edx ; edx = number of pixels to draw
|
||||
mov ebx, ecx ; ecx = number of dwords to draw
|
||||
shr ecx, 2 ; ebx = remaining number of pixels ( <= 3 )
|
||||
and ebx, 3
|
||||
|
||||
rep stosd ; draw the line
|
||||
mov ecx, ebx
|
||||
rep stosb
|
||||
|
||||
pop esi
|
||||
pop edi
|
||||
pop ebp
|
||||
ret 8
|
||||
|
||||
endp
|
||||
|
||||
; direct_filled_rect_f_
|
||||
; eax = color
|
||||
; edx = y_inc
|
||||
; ebx = width
|
||||
; ecx = lines
|
||||
; ebp+8 = dest
|
||||
proc direct_filled_rect_f_ near
|
||||
arg @@dest:dword
|
||||
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
push edi
|
||||
push esi
|
||||
|
||||
mov esi, ecx ; get number of lines to be drawn
|
||||
test esi, esi ; if there are no lines to draw, then return
|
||||
jz @@done
|
||||
|
||||
mov ah, al ; spread color byte out over all 32-bits
|
||||
shl eax, 8 ; so 4 pixels can be written horizontally
|
||||
mov al, ah ; later on
|
||||
shl eax, 8
|
||||
mov al, ah
|
||||
|
||||
mov edi, [@@dest]
|
||||
sub edx, ebx ; edx = y_inc - width
|
||||
; (this is because rep stos will inc edi, so we
|
||||
; just need to y-inc by the remaining amount)
|
||||
|
||||
; *** WARNING: no stack/locals access after this! :) ***
|
||||
push ebp
|
||||
mov ebp, ebx ; get width as number of dwords and remaining bytes
|
||||
and ebp, 3
|
||||
shr ebx, 2
|
||||
|
||||
; esi = loop counter of number of lines to draw
|
||||
; edi = destination to draw at
|
||||
; eax = color to draw (filled out over all 32-bits)
|
||||
; edx = y_inc - width
|
||||
; ebx = number of dwords to draw
|
||||
; ebp = remaining number of pixels to draw after the dwords
|
||||
|
||||
test ebp, ebp ; if there are no remaining bytes after dwords
|
||||
jz @@draw_4 ; then we can do a slightly more optimized draw
|
||||
|
||||
@@draw_4_with_remainder: ; scenario #1: draw dwords + remainder
|
||||
mov ecx, ebx
|
||||
rep stosd
|
||||
mov ecx, ebp
|
||||
rep stosb
|
||||
|
||||
add edi, edx ; move to start of next line
|
||||
dec esi ; decrease loop counter (lines left to draw)
|
||||
jnz @@draw_4_with_remainder
|
||||
jmp @@done ; done drawing, skip to return
|
||||
|
||||
@@draw_4: ; scenario #2: draw dwords only
|
||||
mov ecx, ebx
|
||||
rep stosd
|
||||
|
||||
add edi, edx ; move to start of next line
|
||||
dec esi ; decrease loop counter (lines left to draw)
|
||||
jnz @@draw_4
|
||||
|
||||
@@done:
|
||||
pop ebp
|
||||
pop esi
|
||||
pop edi
|
||||
pop ebp
|
||||
ret 4
|
||||
|
||||
endp
|
||||
|
||||
end
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef DGL_ERROR_H_INCLUDED
|
||||
#define DGL_ERROR_H_INCLUDED
|
||||
#ifndef DGL_DGLERROR_H_INCLUDED
|
||||
#define DGL_DGLERROR_H_INCLUDED
|
||||
|
||||
#include "common.h"
|
||||
#include "dglcmn.h"
|
||||
|
||||
typedef enum {
|
||||
DGL_NONE = 0,
|
20
DGLFIXP.C
Normal file
20
DGLFIXP.C
Normal file
|
@ -0,0 +1,20 @@
|
|||
#include "dglfixp.h"
|
||||
|
||||
fixed fix_sqrt(fixed x) {
|
||||
int t, q, b, r;
|
||||
r = x;
|
||||
b = 0x40000000;
|
||||
q = 0;
|
||||
while (b > 0x40) {
|
||||
t = q + b;
|
||||
if (r >= t) {
|
||||
r -= t;
|
||||
q = t + b;
|
||||
}
|
||||
r <<= 1;
|
||||
b >>= 1;
|
||||
}
|
||||
q >>= 8;
|
||||
return q;
|
||||
}
|
||||
|
89
DGLFIXP.H
Normal file
89
DGLFIXP.H
Normal file
|
@ -0,0 +1,89 @@
|
|||
#ifndef DGL_DGLFIXP_H_INCLUDED
|
||||
#define DGL_DGLFIXP_H_INCLUDED
|
||||
|
||||
#include "dglcmn.h"
|
||||
#include <math.h>
|
||||
|
||||
typedef int fixed;
|
||||
|
||||
#define FP_INT_SHIFT 16
|
||||
#define FP_FLOAT_SHIFT 65536.0f
|
||||
|
||||
static fixed fix_sin(fixed x);
|
||||
static fixed fix_cos(fixed x);
|
||||
static fixed fix_tan(fixed x);
|
||||
|
||||
fixed fix_sqrt(fixed x);
|
||||
|
||||
fixed fix_mul(fixed a, fixed b);
|
||||
#pragma aux fix_mul = \
|
||||
"imul ebx" \
|
||||
"shrd eax, edx, 16" \
|
||||
parm [eax] [ebx] \
|
||||
modify [eax ebx edx];
|
||||
|
||||
fixed fix_div(fixed a, fixed b);
|
||||
#pragma aux fix_div = \
|
||||
"cdq" \
|
||||
"shld edx, eax, 16" \
|
||||
"sal eax, 16" \
|
||||
"idiv ebx" \
|
||||
parm [eax] [ebx] \
|
||||
modify [eax ebx edx];
|
||||
|
||||
#define FTOFIX(f) ((fixed)((f) * FP_FLOAT_SHIFT))
|
||||
#define ITOFIX(i) ((fixed)((i) << FP_INT_SHIFT))
|
||||
#define FIXTOF(x) ((float)((x) / FP_FLOAT_SHIFT))
|
||||
#define FIXTOI(x) ((int)(((x) + 0x8000) >> FP_INT_SHIFT))
|
||||
|
||||
#define FP_1 ITOFIX(1)
|
||||
#define FP_2 ITOFIX(2)
|
||||
#define FP_3 ITOFIX(3)
|
||||
#define FP_4 ITOFIX(4)
|
||||
#define FP_5 ITOFIX(5)
|
||||
#define FP_6 ITOFIX(6)
|
||||
#define FP_7 ITOFIX(7)
|
||||
#define FP_8 ITOFIX(8)
|
||||
#define FP_9 ITOFIX(9)
|
||||
#define FP_10 ITOFIX(10)
|
||||
|
||||
#define FP_16 ITOFIX(16)
|
||||
#define FP_32 ITOFIX(32)
|
||||
#define FP_64 ITOFIX(64)
|
||||
#define FP_128 ITOFIX(128)
|
||||
#define FP_256 ITOFIX(256)
|
||||
|
||||
#define FP_0_1 FTOFIX(0.1f)
|
||||
#define FP_0_2 FTOFIX(0.2f)
|
||||
#define FP_0_3 FTOFIX(0.3f)
|
||||
#define FP_0_4 FTOFIX(0.4f)
|
||||
#define FP_0_5 FTOFIX(0.5f)
|
||||
#define FP_0_6 FTOFIX(0.6f)
|
||||
#define FP_0_7 FTOFIX(0.7f)
|
||||
#define FP_0_8 FTOFIX(0.8f)
|
||||
#define FP_0_9 FTOFIX(0.9f)
|
||||
|
||||
#define FP_0_25 FTOFIX(0.25f)
|
||||
#define FP_0_75 FTOFIX(0.75f)
|
||||
|
||||
#define FP_1_OVER_3 FTOFIX(1.0f / 3.0f)
|
||||
#define FP_2_OVER_3 FTOFIX(2.0f / 3.0f)
|
||||
|
||||
#define FP_PI FTOFIX(3.1415927f)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
static fixed fix_sin(fixed x) {
|
||||
return FTOFIX(sin(FIXTOF(x)));
|
||||
}
|
||||
|
||||
static fixed fix_cos(fixed x) {
|
||||
return FTOFIX(cos(FIXTOF(x)));
|
||||
}
|
||||
|
||||
static fixed fix_tan(fixed x) {
|
||||
return FTOFIX(tan(FIXTOF(x)));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
103
DGLGFX.C
Normal file
103
DGLGFX.C
Normal file
|
@ -0,0 +1,103 @@
|
|||
#include "dglgfx.h"
|
||||
#include "dglblit.h"
|
||||
#include "dglutil.h"
|
||||
#include "dglerror.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
extern void _video_mode(int mode);
|
||||
#pragma aux _video_mode = \
|
||||
"int 0x10" \
|
||||
parm [eax];
|
||||
|
||||
static boolean _initialized = FALSE;
|
||||
|
||||
SURFACE *screen = NULL;
|
||||
|
||||
static SURFACE* surface_create_internal(int width, int height, byte *pixels) {
|
||||
SURFACE *surface = (SURFACE*)malloc(sizeof(SURFACE));
|
||||
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
surface->clip_region = rect(0, 0, width, height);
|
||||
surface->flags = 0;
|
||||
|
||||
if (pixels != NULL) {
|
||||
surface->flags |= SURFACE_FLAGS_ALIASED;
|
||||
surface->pixels = pixels;
|
||||
} else {
|
||||
int size = width * height;
|
||||
surface->pixels = (byte*)malloc(size);
|
||||
mem_fill(surface->pixels, 0, size);
|
||||
}
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
boolean video_init(void) {
|
||||
byte *framebuffer;
|
||||
|
||||
if (_initialized) {
|
||||
dgl_set_error(DGL_VIDEO_ALREADY_INITIALIZED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_video_mode(0x13);
|
||||
|
||||
framebuffer = (byte*)0xa0000;
|
||||
screen = surface_create_internal(320, 200, framebuffer);
|
||||
surface_clear(screen, 0);
|
||||
|
||||
_initialized = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
boolean video_shutdown(void) {
|
||||
if (!_initialized)
|
||||
return TRUE; // don't care
|
||||
|
||||
_video_mode(0x03);
|
||||
|
||||
surface_free(screen);
|
||||
screen = NULL;
|
||||
|
||||
_initialized = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
boolean video_is_initialized(void) {
|
||||
return _initialized;
|
||||
}
|
||||
|
||||
void video_wait_vsync(void) {
|
||||
do {} while (inp(0x3da) & 0x8);
|
||||
do {} while (!(inp(0x3da) & 0x8));
|
||||
}
|
||||
|
||||
SURFACE* surface_create(int width, int height) {
|
||||
return surface_create_internal(width, height, NULL);
|
||||
}
|
||||
|
||||
void surface_free(SURFACE *surface) {
|
||||
if (!surface)
|
||||
return;
|
||||
|
||||
if (!BIT_ISSET(SURFACE_FLAGS_ALIASED, surface->flags))
|
||||
free(surface->pixels);
|
||||
free(surface);
|
||||
}
|
||||
|
||||
void surface_clear(SURFACE *surface, int color) {
|
||||
int length = surface->width * surface->height;
|
||||
mem_fill(surface->pixels, (byte)color, length);
|
||||
}
|
||||
|
||||
void surface_copy(const SURFACE *src, SURFACE *dest) {
|
||||
if (src->width == dest->width && src->height == dest->height) {
|
||||
int length = src->width * src->height;
|
||||
mem_copy(dest->pixels, src->pixels, length);
|
||||
} else {
|
||||
surface_blit(src, dest, 0, 0);
|
||||
}
|
||||
}
|
||||
|
44
DGLGFX.H
Normal file
44
DGLGFX.H
Normal file
|
@ -0,0 +1,44 @@
|
|||
#ifndef DGL_DGLGFX_H_INCLUDED
|
||||
#define DGL_DGLGFX_H_INCLUDED
|
||||
|
||||
#include "dglcmn.h"
|
||||
#include "dglrect.h"
|
||||
|
||||
typedef struct {
|
||||
int width;
|
||||
int height;
|
||||
byte *pixels;
|
||||
RECT clip_region;
|
||||
unsigned int flags;
|
||||
} SURFACE;
|
||||
|
||||
#define SURFACE_FLAGS_ALIASED BIT_0
|
||||
|
||||
extern SURFACE *screen;
|
||||
|
||||
boolean video_init(void);
|
||||
boolean video_shutdown(void);
|
||||
boolean video_is_initialized(void);
|
||||
|
||||
void video_wait_vsync(void);
|
||||
|
||||
SURFACE* surface_create(int width, int height);
|
||||
void surface_free(SURFACE *surface);
|
||||
void surface_clear(SURFACE *surface, int color);
|
||||
void surface_copy(const SURFACE *src, SURFACE *dest);
|
||||
|
||||
static int surface_offset(const SURFACE *surface, int x, int y);
|
||||
static byte* surface_pointer(const SURFACE *surface, int x, int y);
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
static int surface_offset(const SURFACE *surface, int x, int y) {
|
||||
return (surface->width * y) + x;
|
||||
}
|
||||
|
||||
static byte* surface_pointer(const SURFACE *surface, int x, int y) {
|
||||
return surface->pixels + surface_offset(surface, x, y);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,11 +1,8 @@
|
|||
#include "keyboard.h"
|
||||
#include "internal.h"
|
||||
#include "util.h"
|
||||
#include "error.h"
|
||||
#include "dglkbrd.h"
|
||||
#include "dglutil.h"
|
||||
#include "dglerror.h"
|
||||
#include <string.h>
|
||||
#include <dpmi.h>
|
||||
#include <pc.h>
|
||||
#include <sys/nearptr.h>
|
||||
#include <dos.h>
|
||||
|
||||
#define PIC_CTRL_PORT 0x20
|
||||
#define KEYBRD_DATA_PORT 0x60
|
||||
|
@ -33,44 +30,43 @@ volatile KEY _key_scan;
|
|||
|
||||
uword _old_flags;
|
||||
|
||||
_go32_dpmi_seginfo _old_handler;
|
||||
_go32_dpmi_seginfo _new_handler;
|
||||
void (interrupt far *_old_handler)();
|
||||
|
||||
static inline void reset_key_states() {
|
||||
static void reset_key_states() {
|
||||
memset((void*)keys, 0, 128);
|
||||
}
|
||||
|
||||
// waits until the keyboard status port indicates the data port
|
||||
// can be read from once again
|
||||
static inline void wait_kb_data_read() {
|
||||
while ((inportb(KEYBRD_STATUS_PORT) & BIT_0) == 0) {
|
||||
static void wait_kb_data_read() {
|
||||
while ((inp(KEYBRD_STATUS_PORT) & BIT_0) == 0) {
|
||||
}
|
||||
}
|
||||
|
||||
// waits until the keyboard status port indicates the data port
|
||||
// can be written to once again
|
||||
static inline void wait_kb_data_write() {
|
||||
while ((inportb(KEYBRD_STATUS_PORT) & BIT_1) != 0) {
|
||||
static void wait_kb_data_write() {
|
||||
while ((inp(KEYBRD_STATUS_PORT) & BIT_1) != 0) {
|
||||
}
|
||||
}
|
||||
|
||||
// sends data to the keyboard data port. checks for success
|
||||
// and returns TRUE if the data write succeeded
|
||||
static inline boolean send_kb_data(ubyte data) {
|
||||
static boolean send_kb_data(ubyte data) {
|
||||
ubyte result;
|
||||
|
||||
wait_kb_data_write();
|
||||
outportb(KEYBRD_DATA_PORT, data);
|
||||
outp(KEYBRD_DATA_PORT, data);
|
||||
|
||||
wait_kb_data_read();
|
||||
result = inportb(KEYBRD_DATA_PORT);
|
||||
result = inp(KEYBRD_DATA_PORT);
|
||||
return (result == 0xFA);
|
||||
}
|
||||
|
||||
// keyboard interrupt handler
|
||||
void kb_int_handler(void) {
|
||||
void interrupt far kb_int_handler(void) {
|
||||
// read scan code of key that was just pressed
|
||||
_key_scan = inportb(KEYBRD_DATA_PORT);
|
||||
_key_scan = inp(KEYBRD_DATA_PORT);
|
||||
if (_key_scan & 0x80) {
|
||||
// high bit set indicates key was released, clear high bit to get
|
||||
// the actual key scan code
|
||||
|
@ -83,19 +79,18 @@ void kb_int_handler(void) {
|
|||
_key_last_scan = _key_scan;
|
||||
|
||||
// indicate key event was processed to keyboard controller
|
||||
_key_scan = inportb(KEYBRD_CTRL_PORT) | 0x82;
|
||||
outportb(KEYBRD_CTRL_PORT, _key_scan);
|
||||
outportb(KEYBRD_CTRL_PORT, _key_scan & 0x7f);
|
||||
outportb(PIC_CTRL_PORT, 0x20);
|
||||
_key_scan = inp(KEYBRD_CTRL_PORT) | 0x82;
|
||||
outp(KEYBRD_CTRL_PORT, _key_scan);
|
||||
outp(KEYBRD_CTRL_PORT, _key_scan & 0x7f);
|
||||
outp(PIC_CTRL_PORT, 0x20);
|
||||
}
|
||||
END_OF_FUNCTION(kb_int_handler)
|
||||
|
||||
static uword get_kb_flags(void) {
|
||||
return *((uword*)(map_dos_memory(KEYBRD_FLAGS_ADDR)));
|
||||
return *((uword*)KEYBRD_FLAGS_ADDR);
|
||||
}
|
||||
|
||||
static void set_kb_flags(uword flags) {
|
||||
*((uword*)(map_dos_memory(KEYBRD_FLAGS_ADDR))) = flags;
|
||||
*((uword*)KEYBRD_FLAGS_ADDR) = flags;
|
||||
}
|
||||
|
||||
// updates the keyboard indicator LEDs from the num/caps/scroll lock flags
|
||||
|
@ -129,25 +124,18 @@ boolean keyboard_init(void) {
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
LOCK_MEMORY(keys, 128);
|
||||
LOCK_VARIABLE(_key_scan);
|
||||
LOCK_VARIABLE(_key_last_scan);
|
||||
LOCK_FUNCTION(kb_int_handler);
|
||||
|
||||
// preserve old flags
|
||||
_old_flags = get_kb_flags();
|
||||
|
||||
reset_key_states();
|
||||
if (!_install_irq(9, kb_int_handler, &_new_handler, &_old_handler)) {
|
||||
dgl_set_error(DGL_KEYBOARD_IRQ_INSTALL_FAILURE);
|
||||
return FALSE;
|
||||
}
|
||||
_old_handler = _dos_getvect(9);
|
||||
_dos_setvect(9, kb_int_handler);
|
||||
|
||||
// turn off keyboard LEDs since our interrupt handler does not currently
|
||||
// respect the num/caps/scroll lock statuses
|
||||
_disable_interrupts();
|
||||
int_disable();
|
||||
update_kb_led(0);
|
||||
_enable_interrupts();
|
||||
int_enable();
|
||||
|
||||
_installed = TRUE;
|
||||
return TRUE;
|
||||
|
@ -158,14 +146,11 @@ boolean keyboard_shutdown(void) {
|
|||
return TRUE; // don't care
|
||||
|
||||
// reset keyboard LEDs to previous state
|
||||
_disable_interrupts();
|
||||
int_disable();
|
||||
update_kb_led(_old_flags);
|
||||
_enable_interrupts();
|
||||
int_enable();
|
||||
|
||||
if (!_restore_irq(9, &_new_handler, &_old_handler)) {
|
||||
dgl_set_error(DGL_KEYBOARD_IRQ_RESTORE_FAILURE);
|
||||
return FALSE;
|
||||
}
|
||||
_dos_setvect(9, _old_handler);
|
||||
reset_key_states();
|
||||
|
||||
// restore keyboard flags to previous state
|
|
@ -1,15 +1,15 @@
|
|||
#ifndef DGL_KEYBOARD_H_INCLUDED
|
||||
#define DGL_KEYBOARD_H_INCLUDED
|
||||
#ifndef DGL_DGLKYBRD_H_INCLUDED
|
||||
#define DGL_DGLKYBRD_H_INCLUDED
|
||||
|
||||
#include "common.h"
|
||||
#include "keys.h"
|
||||
#include "dglcmn.h"
|
||||
#include "dglkeys.h"
|
||||
|
||||
typedef byte KEY;
|
||||
|
||||
/*
|
||||
* Current state of the keyboard.
|
||||
*/
|
||||
volatile extern ubyte keys[128];
|
||||
extern volatile ubyte keys[128];
|
||||
|
||||
/*
|
||||
* Installs a custom keyboard interrupt handler.
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef DGL_KEYS_H_INCLUDED
|
||||
#define DGL_KEYS_H_INCLUDED
|
||||
#ifndef DGL_DGLKEYS_H_INCLUDED
|
||||
#define DGL_DGLKEYS_H_INCLUDED
|
||||
|
||||
#define KEY_ESC 0x01
|
||||
#define KEY_1 0x02
|
|
@ -1,4 +1,4 @@
|
|||
#include "mathext.h"
|
||||
#include "dglmath.h"
|
||||
#include <math.h>
|
||||
|
||||
float angle_between_i(int x1, int y1, int x2, int y2) {
|
|
@ -1,12 +1,13 @@
|
|||
#ifndef DGL_MATH_H_INCLUDED
|
||||
#define DGL_MATH_H_INCLUDED
|
||||
#ifndef DGL_DGLMATH_H_INCLUDED
|
||||
#define DGL_DGLMATH_H_INCLUDED
|
||||
|
||||
#include "common.h"
|
||||
#include "vector2.h"
|
||||
#include "dglcmn.h"
|
||||
#include "dglvec2.h"
|
||||
#include <math.h>
|
||||
|
||||
#define TOLERANCE 0.00001f
|
||||
|
||||
#define PI 3.1415927f
|
||||
#define PI_OVER_180 (PI / 180.0f)
|
||||
|
||||
#define RADIANS_0 0.0f
|
||||
|
@ -33,41 +34,41 @@ float angle_between_f(float x1, float y1, float x2, float y2);
|
|||
int next_power_of_2(int n);
|
||||
void point_on_circle(float radius, float radians, float *x, float *y);
|
||||
|
||||
static inline VECTOR2F direction_from_angle(float radians);
|
||||
static inline float round(float value);
|
||||
static inline float symmetrical_round(float value);
|
||||
static inline boolean close_enough(float a, float b, float tolerance);
|
||||
static inline boolean power_of_2(int n);
|
||||
static inline float smooth_step(float low, float high, float t);
|
||||
static VECTOR2F direction_from_angle(float radians);
|
||||
static float round(float value);
|
||||
static float symmetrical_round(float value);
|
||||
static boolean close_enough(float a, float b, float tolerance);
|
||||
static boolean power_of_2(int n);
|
||||
static float smooth_step(float low, float high, float t);
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
static inline VECTOR2F direction_from_angle(float radians) {
|
||||
static VECTOR2F direction_from_angle(float radians) {
|
||||
VECTOR2F direction;
|
||||
point_on_circle(1.0f, radians, &direction.x, &direction.y);
|
||||
return direction;
|
||||
}
|
||||
|
||||
static inline float round(float value) {
|
||||
static float round(float value) {
|
||||
return ceil(value + 0.5f);
|
||||
}
|
||||
|
||||
static inline float symmetrical_round(float value) {
|
||||
static float symmetrical_round(float value) {
|
||||
if (value > 0.0f)
|
||||
return floor(value + 0.5f);
|
||||
else
|
||||
return ceil(value - 0.5f);
|
||||
}
|
||||
|
||||
static inline boolean close_enough(float a, float b, float tolerance) {
|
||||
static boolean close_enough(float a, float b, float tolerance) {
|
||||
return fabs((a - b) / ((b == 0.0f) ? 1.0f : b)) < tolerance;
|
||||
}
|
||||
|
||||
static inline boolean power_of_2(int n) {
|
||||
static boolean power_of_2(int n) {
|
||||
return (n != 0) && !(n & (n - 1));
|
||||
}
|
||||
|
||||
static inline float smooth_step(float low, float high, float t) {
|
||||
static float smooth_step(float low, float high, float t) {
|
||||
float n = CLAMP(t, 0.0f, 1.0f);
|
||||
return LERP(low, high, (n * n) * (3.0f - (2.0f * n)));
|
||||
}
|
159
DGLMOUSE.C
Normal file
159
DGLMOUSE.C
Normal file
|
@ -0,0 +1,159 @@
|
|||
#include "dglmouse.h"
|
||||
#include "dglerror.h"
|
||||
#include <string.h>
|
||||
#include <dos.h>
|
||||
|
||||
static boolean _installed = FALSE;
|
||||
static boolean _has_mouse = FALSE;
|
||||
|
||||
volatile int mouse_x;
|
||||
volatile int mouse_y;
|
||||
volatile int mouse_buttons;
|
||||
volatile int mouse_delta_x;
|
||||
volatile int mouse_delta_y;
|
||||
|
||||
static void reset_mouse_state(void) {
|
||||
mouse_x = 0;
|
||||
mouse_y = 0;
|
||||
mouse_buttons = 0;
|
||||
mouse_delta_x = 0;
|
||||
mouse_delta_y = 0;
|
||||
}
|
||||
|
||||
static boolean init_mouse_driver(void) {
|
||||
union REGS regs;
|
||||
|
||||
memset(®s, 0, sizeof(regs));
|
||||
regs.w.ax = 0x00;
|
||||
int386(0x33, ®s, ®s);
|
||||
|
||||
return (regs.w.ax != 0);
|
||||
}
|
||||
|
||||
static void update_mouse_state(void) {
|
||||
union REGS regs;
|
||||
|
||||
memset(®s, 0, sizeof(regs));
|
||||
regs.w.ax = 0x03;
|
||||
int386(0x33, ®s, ®s);
|
||||
mouse_x = (regs.w.cx / 2);
|
||||
mouse_y = regs.w.dx;
|
||||
mouse_buttons = regs.w.bx;
|
||||
mouse_delta_x = 0;
|
||||
mouse_delta_y = 0;
|
||||
}
|
||||
|
||||
#pragma off (check_stack)
|
||||
void __loadds far mouse_int_handler(int eax, int ebx, int ecx, int edx) {
|
||||
#pragma aux mouse_int_handler parm [eax] [ebx] [ecx] [edx]
|
||||
mouse_delta_x = (ecx / 2) - mouse_x;
|
||||
mouse_delta_y = edx - mouse_y;
|
||||
mouse_x = (ecx / 2);
|
||||
mouse_y = edx;
|
||||
mouse_buttons = ebx;
|
||||
}
|
||||
#pragma on (check_stack)
|
||||
|
||||
boolean mouse_init(void) {
|
||||
union REGS regs;
|
||||
struct SREGS sregs;
|
||||
|
||||
if (_installed) {
|
||||
dgl_set_error(DGL_MOUSE_ALREADY_INITIALIZED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
reset_mouse_state();
|
||||
|
||||
_has_mouse = init_mouse_driver();
|
||||
if (!_has_mouse) {
|
||||
_installed = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
update_mouse_state();
|
||||
|
||||
memset(®s, 0, sizeof(regs));
|
||||
memset(&sregs, 0, sizeof(sregs));
|
||||
regs.w.ax = 0x0c;
|
||||
regs.w.cx = 31;
|
||||
regs.x.edx = FP_OFF(mouse_int_handler);
|
||||
sregs.es = FP_SEG(mouse_int_handler);
|
||||
int386x(0x33, ®s, ®s, &sregs);
|
||||
|
||||
_installed = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
boolean mouse_shutdown(void) {
|
||||
union REGS regs;
|
||||
|
||||
if (!_installed)
|
||||
return TRUE; // don't care
|
||||
|
||||
if (!_has_mouse) {
|
||||
_installed = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
memset(®s, 0, sizeof(regs));
|
||||
regs.w.ax = 0x0c;
|
||||
regs.w.cx = 0;
|
||||
int386(0x33, ®s, ®s);
|
||||
|
||||
reset_mouse_state();
|
||||
init_mouse_driver();
|
||||
|
||||
_installed = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
boolean mouse_is_initialized(void) {
|
||||
return _installed;
|
||||
}
|
||||
|
||||
boolean mouse_is_present(void) {
|
||||
return _has_mouse;
|
||||
}
|
||||
|
||||
void mouse_show(void) {
|
||||
union REGS regs;
|
||||
|
||||
if (!_has_mouse)
|
||||
return;
|
||||
|
||||
memset(®s, 0, sizeof(regs));
|
||||
regs.w.ax = 0x01;
|
||||
int386(0x33, ®s, ®s);
|
||||
}
|
||||
|
||||
void mouse_hide(void) {
|
||||
union REGS regs;
|
||||
|
||||
if (!_has_mouse)
|
||||
return;
|
||||
|
||||
memset(®s, 0, sizeof(regs));
|
||||
regs.w.ax = 0x02;
|
||||
int386(0x33, ®s, ®s);
|
||||
}
|
||||
|
||||
void mouse_set_bounds(int min_x, int min_y, int max_x, int max_y) {
|
||||
union REGS regs;
|
||||
|
||||
if (!_has_mouse)
|
||||
return;
|
||||
|
||||
memset(®s, 0, sizeof(regs));
|
||||
|
||||
regs.w.ax = 0x07;
|
||||
regs.w.cx = min_x;
|
||||
regs.w.dx = max_x;
|
||||
int386(0x33, ®s, ®s);
|
||||
|
||||
regs.w.ax = 0x08;
|
||||
regs.w.cx = min_y;
|
||||
regs.w.dx = max_y;
|
||||
int386(0x33, ®s, ®s);
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef DGL_MOUSE_H_INCLUDED
|
||||
#define DGL_MOUSE_H_INCLUDED
|
||||
#ifndef DGL_DGLMOUSE_H_INCLUDED
|
||||
#define DGL_DGLMOUSE_H_INCLUDED
|
||||
|
||||
#include "common.h"
|
||||
#include "dglcmn.h"
|
||||
|
||||
#define MOUSE_LEFTBUTTON 0x01
|
||||
#define MOUSE_RIGHTBUTTON 0x02
|
||||
|
@ -10,27 +10,27 @@
|
|||
/*
|
||||
* Current mouse cursor X position.
|
||||
*/
|
||||
volatile extern int mouse_x;
|
||||
extern volatile int mouse_x;
|
||||
|
||||
/*
|
||||
* Current mouse cursor Y position.
|
||||
*/
|
||||
volatile extern int mouse_y;
|
||||
extern volatile int mouse_y;
|
||||
|
||||
/*
|
||||
* Current state of mouse buttons.
|
||||
*/
|
||||
volatile extern int mouse_buttons;
|
||||
extern volatile int mouse_buttons;
|
||||
|
||||
/*
|
||||
* Amount the cursor moved along the X-axis since the last update.
|
||||
*/
|
||||
volatile extern int mouse_delta_x;
|
||||
extern volatile int mouse_delta_x;
|
||||
|
||||
/*
|
||||
* Amount the cursor moved along the Y-axis since the last update.
|
||||
*/
|
||||
volatile extern int mouse_delta_y;
|
||||
extern volatile int mouse_delta_y;
|
||||
|
||||
/*
|
||||
* Installs a custom mouse handler.
|
||||
|
@ -80,11 +80,11 @@ void mouse_set_bounds(int min_x, int min_y, int max_x, int max_y);
|
|||
* @param button The button to check the status of.
|
||||
* @return TRUE if the button is pressed.
|
||||
*/
|
||||
static inline boolean mouse_button(int button);
|
||||
static boolean mouse_button(int button);
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
static inline boolean mouse_button(int button) {
|
||||
static boolean mouse_button(int button) {
|
||||
return (mouse_buttons & button) != 0;
|
||||
}
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
#ifndef DGL_MATRIX33_H_INCLUDED
|
||||
#define DGL_MATRIX33_H_INCLUDED
|
||||
#ifndef DGL_DGLMAT33_H_INCLUDED
|
||||
#define DGL_DGLMAT33_H_INCLUDED
|
||||
|
||||
#include "common.h"
|
||||
#include "mathext.h"
|
||||
#include "vector2.h"
|
||||
#include "dglcmn.h"
|
||||
#include "dglmath.h"
|
||||
#include "dglvec2.h"
|
||||
#include <math.h>
|
||||
|
||||
#define _M33_11 0
|
||||
|
@ -20,33 +20,33 @@ typedef struct {
|
|||
float m[9];
|
||||
} MATRIX33;
|
||||
|
||||
static inline MATRIX33 matrix33(float m11, float m12, float m13,
|
||||
float m21, float m22, float m23,
|
||||
float m31, float m32, float m33);
|
||||
static inline void matrix33_set(MATRIX33 *m,
|
||||
float m11, float m12, float m13,
|
||||
float m21, float m22, float m23,
|
||||
float m31, float m32, float m33);
|
||||
static MATRIX33 matrix33(float m11, float m12, float m13,
|
||||
float m21, float m22, float m23,
|
||||
float m31, float m32, float m33);
|
||||
static void matrix33_set(MATRIX33 *m,
|
||||
float m11, float m12, float m13,
|
||||
float m21, float m22, float m23,
|
||||
float m31, float m32, float m33);
|
||||
|
||||
static inline MATRIX33 matrix33_from_euler_angles(float x, float y, float z);
|
||||
static inline MATRIX33 matrix33_rotation_x(float radians);
|
||||
static inline MATRIX33 matrix33_rotation_y(float radians);
|
||||
static inline MATRIX33 matrix33_rotation_z(float radians);
|
||||
static MATRIX33 matrix33_from_euler_angles(float x, float y, float z);
|
||||
static MATRIX33 matrix33_rotation_x(float radians);
|
||||
static MATRIX33 matrix33_rotation_y(float radians);
|
||||
static MATRIX33 matrix33_rotation_z(float radians);
|
||||
|
||||
static inline MATRIX33 matrix33_add(MATRIX33 a, MATRIX33 b);
|
||||
static inline MATRIX33 matrix33_sub(MATRIX33 a, MATRIX33 b);
|
||||
static inline MATRIX33 matrix33_mul(MATRIX33 a, MATRIX33 b);
|
||||
static inline MATRIX33 matrix33_scale(MATRIX33 m, float scale);
|
||||
static MATRIX33 matrix33_add(MATRIX33 a, MATRIX33 b);
|
||||
static MATRIX33 matrix33_sub(MATRIX33 a, MATRIX33 b);
|
||||
static MATRIX33 matrix33_mul(MATRIX33 a, MATRIX33 b);
|
||||
static MATRIX33 matrix33_scale(MATRIX33 m, float scale);
|
||||
|
||||
static inline float matrix33_determinant(MATRIX33 m);
|
||||
static inline MATRIX33 matrix33_inverse(MATRIX33 m);
|
||||
static inline MATRIX33 matrix33_transpose(MATRIX33 m);
|
||||
static inline VECTOR2F matrix33_transform(MATRIX33 m, VECTOR2F v);
|
||||
static float matrix33_determinant(MATRIX33 m);
|
||||
static MATRIX33 matrix33_inverse(MATRIX33 m);
|
||||
static MATRIX33 matrix33_transpose(MATRIX33 m);
|
||||
static VECTOR2F matrix33_transform(MATRIX33 m, VECTOR2F v);
|
||||
|
||||
static inline MATRIX33 matrix33_translation_2d(float x, float y);
|
||||
static inline MATRIX33 matrix33_scaling_2d(float x, float y);
|
||||
static inline MATRIX33 matrix33_rotation_2d(float radians);
|
||||
static inline VECTOR2F matrix33_transform_2d(MATRIX33 m, VECTOR2F v);
|
||||
static MATRIX33 matrix33_translation_2d(float x, float y);
|
||||
static MATRIX33 matrix33_scaling_2d(float x, float y);
|
||||
static MATRIX33 matrix33_rotation_2d(float radians);
|
||||
static VECTOR2F matrix33_transform_2d(MATRIX33 m, VECTOR2F v);
|
||||
|
||||
#define IDENTITY_MATRIX33 matrix33(1.0f, 0.0f, 0.0f, \
|
||||
0.0f, 1.0f, 0.0f, \
|
||||
|
@ -54,9 +54,9 @@ static inline VECTOR2F matrix33_transform_2d(MATRIX33 m, VECTOR2F v);
|
|||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
static inline MATRIX33 matrix33(float m11, float m12, float m13,
|
||||
float m21, float m22, float m23,
|
||||
float m31, float m32, float m33) {
|
||||
static MATRIX33 matrix33(float m11, float m12, float m13,
|
||||
float m21, float m22, float m23,
|
||||
float m31, float m32, float m33) {
|
||||
MATRIX33 result;
|
||||
result.m[_M33_11] = m11;
|
||||
result.m[_M33_12] = m12;
|
||||
|
@ -70,10 +70,10 @@ static inline MATRIX33 matrix33(float m11, float m12, float m13,
|
|||
return result;
|
||||
}
|
||||
|
||||
static inline void matrix33_set(MATRIX33 *m,
|
||||
float m11, float m12, float m13,
|
||||
float m21, float m22, float m23,
|
||||
float m31, float m32, float m33) {
|
||||
static void matrix33_set(MATRIX33 *m,
|
||||
float m11, float m12, float m13,
|
||||
float m21, float m22, float m23,
|
||||
float m31, float m32, float m33) {
|
||||
m->m[_M33_11] = m11;
|
||||
m->m[_M33_12] = m12;
|
||||
m->m[_M33_13] = m13;
|
||||
|
@ -85,7 +85,7 @@ static inline void matrix33_set(MATRIX33 *m,
|
|||
m->m[_M33_33] = m33;
|
||||
}
|
||||
|
||||
static inline MATRIX33 matrix33_from_euler_angles(float x, float y, float z) {
|
||||
static MATRIX33 matrix33_from_euler_angles(float x, float y, float z) {
|
||||
MATRIX33 rx, ry, rz;
|
||||
rx = matrix33_rotation_x(x);
|
||||
ry = matrix33_rotation_y(y);
|
||||
|
@ -93,7 +93,7 @@ static inline MATRIX33 matrix33_from_euler_angles(float x, float y, float z) {
|
|||
return matrix33_mul(matrix33_mul(rz, ry), rx);
|
||||
}
|
||||
|
||||
static inline MATRIX33 matrix33_rotation_x(float radians) {
|
||||
static MATRIX33 matrix33_rotation_x(float radians) {
|
||||
MATRIX33 result;
|
||||
float s, c;
|
||||
|
||||
|
@ -115,7 +115,7 @@ static inline MATRIX33 matrix33_rotation_x(float radians) {
|
|||
return result;
|
||||
}
|
||||
|
||||
static inline MATRIX33 matrix33_rotation_y(float radians) {
|
||||
static MATRIX33 matrix33_rotation_y(float radians) {
|
||||
MATRIX33 result;
|
||||
float s, c;
|
||||
|
||||
|
@ -137,7 +137,7 @@ static inline MATRIX33 matrix33_rotation_y(float radians) {
|
|||
return result;
|
||||
}
|
||||
|
||||
static inline MATRIX33 matrix33_rotation_z(float radians) {
|
||||
static MATRIX33 matrix33_rotation_z(float radians) {
|
||||
MATRIX33 result;
|
||||
float s, c;
|
||||
|
||||
|
@ -159,7 +159,7 @@ static inline MATRIX33 matrix33_rotation_z(float radians) {
|
|||
return result;
|
||||
}
|
||||
|
||||
static inline MATRIX33 matrix33_add(MATRIX33 a, MATRIX33 b) {
|
||||
static MATRIX33 matrix33_add(MATRIX33 a, MATRIX33 b) {
|
||||
MATRIX33 result;
|
||||
|
||||
result.m[_M33_11] = a.m[_M33_11] + b.m[_M33_11];
|
||||
|
@ -175,7 +175,7 @@ static inline MATRIX33 matrix33_add(MATRIX33 a, MATRIX33 b) {
|
|||
return result;
|
||||
}
|
||||
|
||||
static inline MATRIX33 matrix33_sub(MATRIX33 a, MATRIX33 b) {
|
||||
static MATRIX33 matrix33_sub(MATRIX33 a, MATRIX33 b) {
|
||||
MATRIX33 result;
|
||||
|
||||
result.m[_M33_11] = a.m[_M33_11] - b.m[_M33_11];
|
||||
|
@ -191,7 +191,7 @@ static inline MATRIX33 matrix33_sub(MATRIX33 a, MATRIX33 b) {
|
|||
return result;
|
||||
}
|
||||
|
||||
static inline MATRIX33 matrix33_mul(MATRIX33 a, MATRIX33 b) {
|
||||
static MATRIX33 matrix33_mul(MATRIX33 a, MATRIX33 b) {
|
||||
MATRIX33 result;
|
||||
|
||||
result.m[_M33_11] = a.m[_M33_11] * b.m[_M33_11] + a.m[_M33_12] * b.m[_M33_21] + a.m[_M33_13] * b.m[_M33_31];
|
||||
|
@ -209,7 +209,7 @@ static inline MATRIX33 matrix33_mul(MATRIX33 a, MATRIX33 b) {
|
|||
return result;
|
||||
}
|
||||
|
||||
static inline MATRIX33 matrix33_scale(MATRIX33 m, float scale) {
|
||||
static MATRIX33 matrix33_scale(MATRIX33 m, float scale) {
|
||||
MATRIX33 result;
|
||||
|
||||
result.m[_M33_11] = m.m[_M33_11] * scale;
|
||||
|
@ -225,7 +225,7 @@ static inline MATRIX33 matrix33_scale(MATRIX33 m, float scale) {
|
|||
return result;
|
||||
}
|
||||
|
||||
static inline float matrix33_determinant(MATRIX33 m) {
|
||||
static float matrix33_determinant(MATRIX33 m) {
|
||||
return
|
||||
m.m[_M33_11] * m.m[_M33_22] * m.m[_M33_33] +
|
||||
m.m[_M33_12] * m.m[_M33_23] * m.m[_M33_31] +
|
||||
|
@ -235,7 +235,7 @@ static inline float matrix33_determinant(MATRIX33 m) {
|
|||
m.m[_M33_13] * m.m[_M33_22] * m.m[_M33_31];
|
||||
}
|
||||
|
||||
static inline MATRIX33 matrix33_inverse(MATRIX33 m) {
|
||||
static MATRIX33 matrix33_inverse(MATRIX33 m) {
|
||||
float d;
|
||||
MATRIX33 result;
|
||||
d = matrix33_determinant(m);
|
||||
|
@ -258,7 +258,7 @@ static inline MATRIX33 matrix33_inverse(MATRIX33 m) {
|
|||
}
|
||||
}
|
||||
|
||||
static inline MATRIX33 matrix33_transpose(MATRIX33 m) {
|
||||
static MATRIX33 matrix33_transpose(MATRIX33 m) {
|
||||
MATRIX33 result;
|
||||
|
||||
result.m[_M33_11] = m.m[_M33_11];
|
||||
|
@ -276,7 +276,7 @@ static inline MATRIX33 matrix33_transpose(MATRIX33 m) {
|
|||
return result;
|
||||
}
|
||||
|
||||
static inline VECTOR2F matrix33_transform(MATRIX33 m, VECTOR2F v) {
|
||||
static VECTOR2F matrix33_transform(MATRIX33 m, VECTOR2F v) {
|
||||
VECTOR2F result;
|
||||
|
||||
result.x = v.x * m.m[_M33_11] + v.y * m.m[_M33_12] + m.m[_M33_13];
|
||||
|
@ -285,7 +285,7 @@ static inline VECTOR2F matrix33_transform(MATRIX33 m, VECTOR2F v) {
|
|||
return result;
|
||||
}
|
||||
|
||||
static inline MATRIX33 matrix33_translation_2d(float x, float y) {
|
||||
static MATRIX33 matrix33_translation_2d(float x, float y) {
|
||||
MATRIX33 result;
|
||||
|
||||
result.m[_M33_11] = 1.0f;
|
||||
|
@ -303,7 +303,7 @@ static inline MATRIX33 matrix33_translation_2d(float x, float y) {
|
|||
return result;
|
||||
}
|
||||
|
||||
static inline MATRIX33 matrix33_scaling_2d(float x, float y) {
|
||||
static MATRIX33 matrix33_scaling_2d(float x, float y) {
|
||||
MATRIX33 result;
|
||||
|
||||
result.m[_M33_11] = x;
|
||||
|
@ -321,11 +321,11 @@ static inline MATRIX33 matrix33_scaling_2d(float x, float y) {
|
|||
return result;
|
||||
}
|
||||
|
||||
static inline MATRIX33 matrix33_rotation_2d(float radians) {
|
||||
static MATRIX33 matrix33_rotation_2d(float radians) {
|
||||
return matrix33_rotation_z(radians);
|
||||
}
|
||||
|
||||
static inline VECTOR2F matrix33_transform_2d(MATRIX33 m, VECTOR2F v) {
|
||||
static VECTOR2F matrix33_transform_2d(MATRIX33 m, VECTOR2F v) {
|
||||
VECTOR2F result;
|
||||
|
||||
result.x = v.x * m.m[_M33_11] + v.y * m.m[_M33_12] + m.m[_M33_13];
|
109
DGLPAL.C
Normal file
109
DGLPAL.C
Normal file
|
@ -0,0 +1,109 @@
|
|||
#include "dglpal.h"
|
||||
#include "dglgfx.h"
|
||||
#include <stdlib.h>
|
||||
#include <dos.h>
|
||||
|
||||
void pal_set_color(byte color, byte r, byte g, byte b) {
|
||||
outp(0x3c6, 0xff);
|
||||
outp(0x3c8, color);
|
||||
outp(0x3c9, r);
|
||||
outp(0x3c9, g);
|
||||
outp(0x3c9, b);
|
||||
}
|
||||
|
||||
void pal_get_color(byte color, byte *r, byte *g, byte *b) {
|
||||
outp(0x3c6, 0xff);
|
||||
outp(0x3c7, color);
|
||||
*r = inp(0x3c9);
|
||||
*g = inp(0x3c9);
|
||||
*b = inp(0x3c9);
|
||||
}
|
||||
|
||||
void pal_set(const byte *palette) {
|
||||
int i = 0;
|
||||
for (i = 0; i < 256; ++i) {
|
||||
pal_set_color(i, palette[0], palette[1], palette[2]);
|
||||
palette += 3;
|
||||
}
|
||||
}
|
||||
|
||||
void pal_get(byte *palette) {
|
||||
int i = 0;
|
||||
for (i = 0; i < 256; ++i) {
|
||||
pal_get_color(i, palette, palette + 1, palette + 2);
|
||||
palette += 3;
|
||||
}
|
||||
}
|
||||
|
||||
static boolean fade_color(int color, byte r, byte g, byte b, int step) {
|
||||
byte red, green, blue;
|
||||
byte diff_r, diff_g, diff_b;
|
||||
boolean color_diff = FALSE;
|
||||
|
||||
pal_get_color(color, &red, &green, &blue);
|
||||
|
||||
if (red != r) {
|
||||
color_diff = TRUE;
|
||||
diff_r = abs(red - r);
|
||||
if (red > r)
|
||||
red -= min(step, diff_r);
|
||||
else
|
||||
red += min(step, diff_r);
|
||||
}
|
||||
|
||||
if (green != g) {
|
||||
color_diff = TRUE;
|
||||
diff_g = abs(green - g);
|
||||
if (green > g)
|
||||
green -= min(step, diff_g);
|
||||
else
|
||||
green += min(step, diff_g);
|
||||
}
|
||||
|
||||
if (blue != b) {
|
||||
color_diff = TRUE;
|
||||
diff_b = abs(blue - b);
|
||||
if (blue > b)
|
||||
blue -= min(step, diff_b);
|
||||
else
|
||||
blue += min(step, diff_b);
|
||||
}
|
||||
|
||||
if (color_diff)
|
||||
pal_set_color(color, red, green, blue);
|
||||
|
||||
return (red == r && green == g && blue == b);
|
||||
}
|
||||
|
||||
void pal_fade_range_to_color(int start, int end, byte r, byte g, byte b, int step) {
|
||||
int i;
|
||||
boolean done = FALSE;
|
||||
|
||||
step = abs(step);
|
||||
|
||||
while (!done) {
|
||||
done = TRUE;
|
||||
video_wait_vsync();
|
||||
for (i = start; i <= end; ++i) {
|
||||
if (!fade_color(i, r, g, b, step))
|
||||
done = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pal_fade_range_to_palette(int start, int end, const byte *palette, int step) {
|
||||
int color, i;
|
||||
boolean done = FALSE;
|
||||
|
||||
step = abs(step);
|
||||
|
||||
while (!done) {
|
||||
done = TRUE;
|
||||
video_wait_vsync();
|
||||
for (i = (start * 3), color = start; color <= end; ++color, i += 3) {
|
||||
if (!fade_color(color, palette[i], palette[i + 1], palette[i + 2], step))
|
||||
done = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
27
DGLPAL.H
Normal file
27
DGLPAL.H
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef DGL_DGLPAL_H_INCLUDED
|
||||
#define DGL_DGLPAL_H_INCLUDED
|
||||
|
||||
#include "dglcmn.h"
|
||||
|
||||
void pal_set_color(byte color, byte r, byte g, byte b);
|
||||
void pal_get_color(byte color, byte *r, byte *g, byte *b);
|
||||
void pal_set(const byte *palette);
|
||||
void pal_get(byte *palette);
|
||||
|
||||
void pal_fade_range_to_color(int start, int end, byte r, byte g, byte b, int step);
|
||||
void pal_fade_range_to_palette(int start, int end, const byte *palette, int step);
|
||||
static void pal_fade_to_color(byte r, byte g, byte b, int step);
|
||||
static void pal_fade_to_palette(const byte *palette, int step);
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
static void pal_fade_to_color(byte r, byte g, byte b, int step) {
|
||||
pal_fade_range_to_color(0, 255, r, g, b, step);
|
||||
}
|
||||
|
||||
static void pal_fade_to_palette(const byte *palette, int step) {
|
||||
pal_fade_range_to_palette(0, 255, palette, step);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,8 +1,10 @@
|
|||
#include "pcx.h"
|
||||
#include "gfx.h"
|
||||
#include "draw.h"
|
||||
#include "error.h"
|
||||
#include "dglpcx.h"
|
||||
#include "dglgfx.h"
|
||||
#include "dglpal.h"
|
||||
#include "dgldraw.h"
|
||||
#include "dglerror.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct {
|
||||
byte manufacturer;
|
||||
|
@ -28,7 +30,7 @@ typedef struct {
|
|||
SURFACE* pcx_load(const char *filename, byte *pcx_palette) {
|
||||
FILE *fp;
|
||||
PCX_HEADER header;
|
||||
int i, n, count;
|
||||
int i, n, count, x, y;
|
||||
SURFACE *pcx;
|
||||
ubyte data;
|
||||
|
||||
|
@ -56,27 +58,32 @@ SURFACE* pcx_load(const char *filename, byte *pcx_palette) {
|
|||
|
||||
pcx = surface_create(header.width + 1, header.height + 1);
|
||||
|
||||
// read pixel data
|
||||
i = 0;
|
||||
while (i < (header.width * header.height)) {
|
||||
n = fread(&data, 1, 1, fp);
|
||||
if (n == -1)
|
||||
goto pcx_load_error;
|
||||
i = 0;
|
||||
for (y = 0; y < (header.height + 1); ++y) {
|
||||
// write pixels out per-scanline (technically this is what the pcx
|
||||
// standard specifies, though a lot of pcx loaders don't do this).
|
||||
x = 0;
|
||||
while (x < header.bytes_per_line) {
|
||||
// read pixel (or RLE count...)
|
||||
data = fgetc(fp);
|
||||
if ((data & 0xc0) == 0xc0) {
|
||||
// was an RLE count, pixel is next byte
|
||||
count = data & 0x3f;
|
||||
data = fgetc(fp);
|
||||
} else {
|
||||
count = 1;
|
||||
}
|
||||
|
||||
if (data >= 192) {
|
||||
count = data - 192;
|
||||
n = fread(&data, 1, 1, fp);
|
||||
if (n == -1)
|
||||
goto pcx_load_error;
|
||||
|
||||
while (count > 0) {
|
||||
pcx->pixels[i++] = data;
|
||||
count--;
|
||||
}
|
||||
} else {
|
||||
pcx->pixels[i++] = data;
|
||||
}
|
||||
}
|
||||
// store this pixel colour the specified number of times
|
||||
while (count--) {
|
||||
if (x < pcx->width) {
|
||||
pcx->pixels[i] = data;
|
||||
}
|
||||
++i;
|
||||
++x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// read palette (only if needed)
|
||||
if (pcx_palette) {
|
||||
|
@ -100,7 +107,7 @@ pcx_load_error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static inline boolean write_pcx_data(FILE *fp, int run_count, byte pixel) {
|
||||
static boolean write_pcx_data(FILE *fp, int run_count, byte pixel) {
|
||||
int n;
|
||||
|
||||
if ((run_count > 1) || ((pixel & 0xc0) == 0xc0)) {
|
||||
|
@ -198,7 +205,7 @@ boolean pcx_save(const char *filename, const SURFACE *src, const byte *palette)
|
|||
}
|
||||
} else {
|
||||
for (i = 0; i < 256; ++i) {
|
||||
video_get_color(i, &r, &g, &b);
|
||||
pal_get_color(i, &r, &g, &b);
|
||||
|
||||
n = fputc(r << 2, fp);
|
||||
if (n == -1)
|
|
@ -1,8 +1,8 @@
|
|||
#ifndef DGL_PCX_H_INCLUDED
|
||||
#define DGL_PCX_H_INCLUDED
|
||||
#ifndef DGL_DGLPCX_H_INCLUDED
|
||||
#define DGL_DGLPCX_H_INCLUDED
|
||||
|
||||
#include "common.h"
|
||||
#include "gfx.h"
|
||||
#include "dglcmn.h"
|
||||
#include "dglgfx.h"
|
||||
|
||||
SURFACE* pcx_load(const char *filename, byte *pcx_palette);
|
||||
boolean pcx_save(const char *filename, const SURFACE *src, const byte *palette);
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef DGL_RECT_H_INCLUDED
|
||||
#define DGL_RECT_H_INCLUDED
|
||||
#ifndef DGL_DGLRECT_H_INCLUDED
|
||||
#define DGL_DGLRECT_H_INCLUDED
|
||||
|
||||
typedef struct {
|
||||
int x;
|
||||
|
@ -8,13 +8,13 @@ typedef struct {
|
|||
int height;
|
||||
} RECT;
|
||||
|
||||
static inline RECT rect(int x, int y, int width, int height);
|
||||
static inline int rect_right(const RECT *r);
|
||||
static inline int rect_bottom(const RECT *r);
|
||||
static RECT rect(int x, int y, int width, int height);
|
||||
static int rect_right(const RECT *r);
|
||||
static int rect_bottom(const RECT *r);
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
static inline RECT rect(int x, int y, int width, int height) {
|
||||
static RECT rect(int x, int y, int width, int height) {
|
||||
RECT result;
|
||||
result.x = x;
|
||||
result.y = y;
|
||||
|
@ -23,14 +23,14 @@ static inline RECT rect(int x, int y, int width, int height) {
|
|||
return result;
|
||||
}
|
||||
|
||||
static inline int rect_right(const RECT *r) {
|
||||
static int rect_right(const RECT *r) {
|
||||
if (r->width)
|
||||
return r->x + r->width - 1;
|
||||
else
|
||||
return r->x;
|
||||
}
|
||||
|
||||
static inline int rect_bottom(const RECT *r) {
|
||||
static int rect_bottom(const RECT *r) {
|
||||
if (r->height)
|
||||
return r->y + r->height - 1;
|
||||
else
|
22
DGLUTIL.C
Normal file
22
DGLUTIL.C
Normal file
|
@ -0,0 +1,22 @@
|
|||
#include "dglutil.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#define SYS_CLOCKS_PER_SEC (1000.0f / 55.0f)
|
||||
|
||||
|
||||
int sys_clock() {
|
||||
return *((int*)0x046c);
|
||||
}
|
||||
|
||||
float clock_ticks_to_seconds(int clocks) {
|
||||
return clocks / (float)SYS_CLOCKS_PER_SEC;
|
||||
}
|
||||
|
||||
int rnd_int(int low, int high) {
|
||||
return rand() % ((high - low) + 1) + low;
|
||||
}
|
||||
|
||||
float rnd_float(float low, float high) {
|
||||
return low + (rand() / (float)RAND_MAX) * (high - low);
|
||||
}
|
||||
|
100
DGLUTIL.H
Normal file
100
DGLUTIL.H
Normal file
|
@ -0,0 +1,100 @@
|
|||
#ifndef DGL_DGLUTIL_H_INCLUDED
|
||||
#define DGL_DGLUTIL_H_INCLUDED
|
||||
|
||||
#include "dglcmn.h"
|
||||
|
||||
#define SWAP(type, a, b) \
|
||||
do { \
|
||||
type __tmp = a; \
|
||||
a = b; \
|
||||
b = __tmp; \
|
||||
} while (0)
|
||||
|
||||
#define SIGN(x) (((x) < 0) ? -1 : (((x) > 0) ? 1 : 0))
|
||||
|
||||
int sys_clock();
|
||||
float clock_ticks_to_seconds(int clocks);
|
||||
|
||||
int rnd_int(int low, int high);
|
||||
float rnd_float(float low, float high);
|
||||
|
||||
void int_enable(void);
|
||||
#pragma aux int_enable = "sti"
|
||||
|
||||
void int_disable(void);
|
||||
#pragma aux int_disable = "cli"
|
||||
|
||||
int fill32(byte value);
|
||||
#pragma aux fill32 = \
|
||||
"mov ah, al" \
|
||||
"shl eax, 8" \
|
||||
"mov al, ah" \
|
||||
"shl eax, 8" \
|
||||
"mov al, ah" \
|
||||
parm [eax] \
|
||||
value [eax];
|
||||
|
||||
void REP_MOVSD(const void *src, void *dest, int num_dwords);
|
||||
#pragma aux REP_MOVSD = \
|
||||
"cld" \
|
||||
"rep movsd" \
|
||||
parm [esi] [edi] [ecx];
|
||||
|
||||
void REP_MOVSB(const void *src, void *dest, int num_bytes);
|
||||
#pragma aux REP_MOVSB = \
|
||||
"cld" \
|
||||
"rep movsb" \
|
||||
parm [esi] [edi] [ecx];
|
||||
|
||||
void REP_STOSD(int value, void *dest, int num_dwords);
|
||||
#pragma aux REP_STOSD = \
|
||||
"cld" \
|
||||
"rep stosd" \
|
||||
parm [eax] [edi] [ecx];
|
||||
|
||||
void REP_STOSB(int value, void *dest, int num_bytes);
|
||||
#pragma aux REP_STOSB = \
|
||||
"cld" \
|
||||
"rep stosb" \
|
||||
parm [eax] [edi] [ecx];
|
||||
|
||||
void mem_fill(void *dest, byte value, int num_bytes);
|
||||
#pragma aux mem_fill = \
|
||||
"mov ah, al" \
|
||||
"shl eax, 8" \
|
||||
"mov al, ah" \
|
||||
"shl eax, 8" \
|
||||
"mov al, ah" \
|
||||
"mov ebx, ecx" \
|
||||
"shr ecx, 2" \
|
||||
"and ebx, 3" \
|
||||
"rep stosd" \
|
||||
"mov ecx, ebx" \
|
||||
"rep stosb" \
|
||||
parm [edi] [eax] [ecx] \
|
||||
modify [eax ebx ecx edi];
|
||||
|
||||
void mem_fill32(void *dest, int value, int num_bytes);
|
||||
#pragma aux mem_fill32 = \
|
||||
"mov ebx, ecx" \
|
||||
"shr ecx, 2" \
|
||||
"and ebx, 3" \
|
||||
"rep stosd" \
|
||||
"mov ecx, ebx" \
|
||||
"rep stosb" \
|
||||
parm [edi] [eax] [ecx] \
|
||||
modify [eax ebx ecx edi];
|
||||
|
||||
void mem_copy(void *dest, const void *src, int num_bytes);
|
||||
#pragma aux mem_copy = \
|
||||
"mov ebx, ecx" \
|
||||
"shr ecx, 2" \
|
||||
"and ebx, 3" \
|
||||
"rep movsd" \
|
||||
"mov ecx, ebx" \
|
||||
"rep movsb" \
|
||||
parm [edi] [esi] [ecx] \
|
||||
modify [eax ebx ecx];
|
||||
|
||||
#endif
|
||||
|
436
DGLVEC2.H
Normal file
436
DGLVEC2.H
Normal file
|
@ -0,0 +1,436 @@
|
|||
#ifndef DGL_DGLVEC2_H_INCLUDED
|
||||
#define DGL_DGLVEC2_H_INCLUDED
|
||||
|
||||
#include <math.h>
|
||||
#include "dglcmn.h"
|
||||
#include "dglfixp.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
int x;
|
||||
int y;
|
||||
} VECTOR2I;
|
||||
|
||||
static VECTOR2I vector2i(int x, int y);
|
||||
static void vector2i_set(VECTOR2I *v, int x, int y);
|
||||
static boolean vector2i_equals(VECTOR2I a, VECTOR2I b);
|
||||
static VECTOR2I vector2i_add(VECTOR2I a, VECTOR2I b);
|
||||
static VECTOR2I vector2i_sub(VECTOR2I a, VECTOR2I b);
|
||||
static VECTOR2I vector2i_mul(VECTOR2I a, VECTOR2I b);
|
||||
static VECTOR2I vector2i_muls(VECTOR2I v, int n);
|
||||
static VECTOR2I vector2i_div(VECTOR2I a, VECTOR2I b);
|
||||
static VECTOR2I vector2i_divs(VECTOR2I v, int n);
|
||||
static int vector2i_distance(VECTOR2I a, VECTOR2I b);
|
||||
static int vector2i_distancesq(VECTOR2I a, VECTOR2I b);
|
||||
static int vector2i_dot(VECTOR2I a, VECTOR2I b);
|
||||
static int vector2i_length(VECTOR2I v);
|
||||
static int vector2i_lengthsq(VECTOR2I v);
|
||||
static VECTOR2I vector2i_lerp(VECTOR2I a, VECTOR2I b, float lerp);
|
||||
|
||||
#define ZERO_VECTOR2I vector2i(0, 0)
|
||||
#define UP_VECTOR2I vector2i(0, -1);
|
||||
#define DOWN_VECTOR2I vector2i(0, 1);
|
||||
#define LEFT_VECTOR2I vector2i(-1, 0);
|
||||
#define RIGHT_VECTOR2I vector2i(1, 0);
|
||||
#define UNIT_X_VECTOR2I vector2i(1, 0);
|
||||
#define UNIT_Y_VECTOR2I vector2i(0, 1);
|
||||
|
||||
|
||||
typedef struct {
|
||||
float x;
|
||||
float y;
|
||||
} VECTOR2F;
|
||||
|
||||
static VECTOR2F vector2f(float x, float y);
|
||||
static void vector2f_set(VECTOR2F *v, float x, float y);
|
||||
static boolean vector2f_equals(VECTOR2F a, VECTOR2F b);
|
||||
static VECTOR2F vector2f_add(VECTOR2F a, VECTOR2F b);
|
||||
static VECTOR2F vector2f_sub(VECTOR2F a, VECTOR2F b);
|
||||
static VECTOR2F vector2f_mul(VECTOR2F a, VECTOR2F b);
|
||||
static VECTOR2F vector2f_muls(VECTOR2F v, float n);
|
||||
static VECTOR2F vector2f_div(VECTOR2F a, VECTOR2F b);
|
||||
static VECTOR2F vector2f_divs(VECTOR2F v, float n);
|
||||
static float vector2f_distance(VECTOR2F a, VECTOR2F b);
|
||||
static float vector2f_distancesq(VECTOR2F a, VECTOR2F b);
|
||||
static float vector2f_dot(VECTOR2F a, VECTOR2F b);
|
||||
static float vector2f_length(VECTOR2F v);
|
||||
static float vector2f_lengthsq(VECTOR2F v);
|
||||
static VECTOR2F vector2f_normalize(VECTOR2F v);
|
||||
static VECTOR2F vector2f_set_length(VECTOR2F v, float length);
|
||||
static VECTOR2F vector2f_lerp(VECTOR2F a, VECTOR2F b, float lerp);
|
||||
|
||||
#define ZERO_VECTOR2F vector2f(0.0f, 0.0f)
|
||||
#define UP_VECTOR2F vector2f(0.0f, -1.0f);
|
||||
#define DOWN_VECTOR2F vector2f(0.0f, 1.0f);
|
||||
#define LEFT_VECTOR2F vector2f(-1.0f, 0.0f);
|
||||
#define RIGHT_VECTOR2F vector2f(1.0f, 0.0f);
|
||||
#define UNIT_X_VECTOR2F vector2f(1.0f, 0.0f);
|
||||
#define UNIT_Y_VECTOR2F vector2f(0.0f, 1.0f);
|
||||
|
||||
|
||||
typedef struct {
|
||||
fixed x;
|
||||
fixed y;
|
||||
} VECTOR2FP;
|
||||
|
||||
static VECTOR2FP vector2fp(fixed x, fixed y);
|
||||
static void vector2fp_set(VECTOR2FP *v, fixed x, fixed y);
|
||||
static boolean vector2fp_equals(VECTOR2FP a, VECTOR2FP b);
|
||||
static VECTOR2FP vector2fp_add(VECTOR2FP a, VECTOR2FP b);
|
||||
static VECTOR2FP vector2fp_sub(VECTOR2FP a, VECTOR2FP b);
|
||||
static VECTOR2FP vector2fp_mul(VECTOR2FP a, VECTOR2FP b);
|
||||
static VECTOR2FP vector2fp_muls(VECTOR2FP v, fixed n);
|
||||
static VECTOR2FP vector2fp_div(VECTOR2FP a, VECTOR2FP b);
|
||||
static VECTOR2FP vector2fp_divs(VECTOR2FP v, fixed n);
|
||||
static fixed vector2fp_distance(VECTOR2FP a, VECTOR2FP b);
|
||||
static fixed vector2fp_distancesq(VECTOR2FP a, VECTOR2FP b);
|
||||
static fixed vector2fp_dot(VECTOR2FP a, VECTOR2FP b);
|
||||
static fixed vector2fp_length(VECTOR2FP v);
|
||||
static fixed vector2fp_lengthsq(VECTOR2FP v);
|
||||
static VECTOR2FP vector2fp_normalize(VECTOR2FP v);
|
||||
static VECTOR2FP vector2fp_set_length(VECTOR2FP v, fixed length);
|
||||
static VECTOR2FP vector2fp_lerp(VECTOR2FP a, VECTOR2FP b, fixed lerp);
|
||||
|
||||
#define ZERO_VECTOR2FP vector2fp(0, 0)
|
||||
#define UP_VECTOR2FP vector2fp(0, (-1 << 16));
|
||||
#define DOWN_VECTOR2FP vector2fp(0, (1 << 16));
|
||||
#define LEFT_VECTOR2FP vector2fp((-1 << 16), 0);
|
||||
#define RIGHT_VECTOR2FP vector2fp((1 << 16), 0);
|
||||
#define UNIT_X_VECTOR2FP vector2fp((1 << 16), 0);
|
||||
#define UNIT_Y_VECTOR2FP vector2fp(0, (1 << 16));
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
static VECTOR2I vector2i(int x, int y) {
|
||||
VECTOR2I v;
|
||||
v.x = x;
|
||||
v.y = y;
|
||||
return v;
|
||||
}
|
||||
|
||||
static VECTOR2F vector2f(float x, float y) {
|
||||
VECTOR2F v;
|
||||
v.x = x;
|
||||
v.y = y;
|
||||
return v;
|
||||
}
|
||||
|
||||
static VECTOR2FP vector2fp(fixed x, fixed y) {
|
||||
VECTOR2FP v;
|
||||
v.x = x;
|
||||
v.y = y;
|
||||
return v;
|
||||
}
|
||||
|
||||
static void vector2i_set(VECTOR2I *v, int x, int y) {
|
||||
v->x = x;
|
||||
v->y = y;
|
||||
}
|
||||
|
||||
static void vector2f_set(VECTOR2F *v, float x, float y) {
|
||||
v->x = x;
|
||||
v->y = y;
|
||||
}
|
||||
|
||||
static void vector2fp_set(VECTOR2FP *v, fixed x, fixed y) {
|
||||
v->x = x;
|
||||
v->y = y;
|
||||
}
|
||||
|
||||
static boolean vector2i_equals(VECTOR2I a, VECTOR2I b) {
|
||||
return (a.x == b.x && a.y == b.y);
|
||||
}
|
||||
|
||||
static boolean vector2f_equals(VECTOR2F a, VECTOR2F b) {
|
||||
return (a.x == b.x && a.y == b.y);
|
||||
}
|
||||
|
||||
static boolean vector2fp_equals(VECTOR2FP a, VECTOR2FP b) {
|
||||
return (a.x == b.x && a.y == b.y);
|
||||
}
|
||||
|
||||
static VECTOR2I vector2i_add(VECTOR2I a, VECTOR2I b) {
|
||||
VECTOR2I result;
|
||||
result.x = a.x + b.x;
|
||||
result.y = a.y + b.y;
|
||||
return result;
|
||||
}
|
||||
|
||||
static VECTOR2F vector2f_add(VECTOR2F a, VECTOR2F b) {
|
||||
VECTOR2F result;
|
||||
result.x = a.x + b.x;
|
||||
result.y = a.y + b.y;
|
||||
return result;
|
||||
}
|
||||
|
||||
static VECTOR2FP vector2fp_add(VECTOR2FP a, VECTOR2FP b) {
|
||||
VECTOR2FP result;
|
||||
result.x = a.x + b.x;
|
||||
result.y = a.y + b.y;
|
||||
return result;
|
||||
}
|
||||
|
||||
static VECTOR2I vector2i_sub(VECTOR2I a, VECTOR2I b) {
|
||||
VECTOR2I result;
|
||||
result.x = a.x - b.x;
|
||||
result.y = a.y - b.y;
|
||||
return result;
|
||||
}
|
||||
|
||||
static VECTOR2F vector2f_sub(VECTOR2F a, VECTOR2F b) {
|
||||
VECTOR2F result;
|
||||
result.x = a.x - b.x;
|
||||
result.y = a.y - b.y;
|
||||
return result;
|
||||
}
|
||||
|
||||
static VECTOR2FP vector2fp_sub(VECTOR2FP a, VECTOR2FP b) {
|
||||
VECTOR2FP result;
|
||||
result.x = a.x - b.x;
|
||||
result.y = a.y - b.y;
|
||||
return result;
|
||||
}
|
||||
|
||||
static VECTOR2I vector2i_mul(VECTOR2I a, VECTOR2I b) {
|
||||
VECTOR2I result;
|
||||
result.x = a.x * b.x;
|
||||
result.y = a.y * b.y;
|
||||
return result;
|
||||
}
|
||||
|
||||
static VECTOR2F vector2f_mul(VECTOR2F a, VECTOR2F b) {
|
||||
VECTOR2F result;
|
||||
result.x = a.x * b.x;
|
||||
result.y = a.y * b.y;
|
||||
return result;
|
||||
}
|
||||
|
||||
static VECTOR2FP vector2fp_mul(VECTOR2FP a, VECTOR2FP b) {
|
||||
VECTOR2FP result;
|
||||
result.x = fix_mul(a.x, b.x);
|
||||
result.y = fix_mul(a.y, b.y);
|
||||
return result;
|
||||
}
|
||||
|
||||
static VECTOR2I vector2i_muls(VECTOR2I v, int n) {
|
||||
VECTOR2I result;
|
||||
result.x = v.x * n;
|
||||
result.y = v.y * n;
|
||||
return result;
|
||||
}
|
||||
|
||||
static VECTOR2F vector2f_muls(VECTOR2F v, float n) {
|
||||
VECTOR2F result;
|
||||
result.x = v.x * n;
|
||||
result.y = v.y * n;
|
||||
return result;
|
||||
}
|
||||
|
||||
static VECTOR2FP vector2fp_muls(VECTOR2FP v, fixed n) {
|
||||
VECTOR2FP result;
|
||||
result.x = fix_mul(v.x, n);
|
||||
result.y = fix_mul(v.y, n);
|
||||
return result;
|
||||
}
|
||||
|
||||
static VECTOR2I vector2i_div(VECTOR2I a, VECTOR2I b) {
|
||||
VECTOR2I result;
|
||||
result.x = a.x / b.x;
|
||||
result.y = a.y / b.y;
|
||||
return result;
|
||||
}
|
||||
|
||||
static VECTOR2F vector2f_div(VECTOR2F a, VECTOR2F b) {
|
||||
VECTOR2F result;
|
||||
result.x = a.x / b.x;
|
||||
result.y = a.y / b.y;
|
||||
return result;
|
||||
}
|
||||
|
||||
static VECTOR2FP vector2fp_div(VECTOR2FP a, VECTOR2FP b) {
|
||||
VECTOR2FP result;
|
||||
result.x = fix_div(a.x, b.x);
|
||||
result.y = fix_div(a.y, b.y);
|
||||
return result;
|
||||
}
|
||||
|
||||
static VECTOR2I vector2i_divs(VECTOR2I v, int n) {
|
||||
VECTOR2I result;
|
||||
result.x = v.x / n;
|
||||
result.y = v.y / n;
|
||||
return result;
|
||||
}
|
||||
|
||||
static VECTOR2F vector2f_divs(VECTOR2F v, float n) {
|
||||
VECTOR2F result;
|
||||
result.x = v.x / n;
|
||||
result.y = v.y / n;
|
||||
return result;
|
||||
}
|
||||
|
||||
static VECTOR2FP vector2fp_divs(VECTOR2FP v, fixed n) {
|
||||
VECTOR2FP result;
|
||||
result.x = fix_div(v.x, n);
|
||||
result.y = fix_div(v.y, n);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int vector2i_distance(VECTOR2I a, VECTOR2I b) {
|
||||
return (int)sqrt(
|
||||
((b.x - a.x) * (b.x - a.x)) +
|
||||
((b.y - a.y) * (b.y - a.y))
|
||||
);
|
||||
}
|
||||
|
||||
static float vector2f_distance(VECTOR2F a, VECTOR2F b) {
|
||||
return (float)sqrt(
|
||||
((b.x - a.x) * (b.x - a.x)) +
|
||||
((b.y - a.y) * (b.y - a.y))
|
||||
);
|
||||
}
|
||||
|
||||
static fixed vector2fp_distance(VECTOR2FP a, VECTOR2FP b) {
|
||||
return fix_sqrt(
|
||||
fix_mul((b.x - a.x), (b.x - a.x)) +
|
||||
fix_mul((b.y - a.y), (b.y - a.y))
|
||||
);
|
||||
}
|
||||
|
||||
static int vector2i_distancesq(VECTOR2I a, VECTOR2I b) {
|
||||
return
|
||||
((b.x - a.x) * (b.x - a.x)) +
|
||||
((b.y - a.y) * (b.y - a.y));
|
||||
}
|
||||
|
||||
static float vector2f_distancesq(VECTOR2F a, VECTOR2F b) {
|
||||
return
|
||||
((b.x - a.x) * (b.x - a.x)) +
|
||||
((b.y - a.y) * (b.y - a.y));
|
||||
}
|
||||
|
||||
static fixed vector2fp_distancesq(VECTOR2FP a, VECTOR2FP b) {
|
||||
return
|
||||
fix_mul((b.x - a.x), (b.x - a.x)) +
|
||||
fix_mul((b.y - a.y), (b.y - a.y));
|
||||
}
|
||||
|
||||
static int vector2i_dot(VECTOR2I a, VECTOR2I b) {
|
||||
return
|
||||
(a.x * b.x) +
|
||||
(a.y * b.y);
|
||||
}
|
||||
|
||||
static float vector2f_dot(VECTOR2F a, VECTOR2F b) {
|
||||
return
|
||||
(a.x * b.x) +
|
||||
(a.y * b.y);
|
||||
}
|
||||
|
||||
static fixed vector2fp_dot(VECTOR2FP a, VECTOR2FP b) {
|
||||
return
|
||||
fix_mul(a.x, b.x) +
|
||||
fix_mul(a.y, b.y);
|
||||
}
|
||||
|
||||
static int vector2i_length(VECTOR2I v) {
|
||||
return sqrt(
|
||||
(v.x * v.x) +
|
||||
(v.y * v.y)
|
||||
);
|
||||
}
|
||||
|
||||
static float vector2f_length(VECTOR2F v) {
|
||||
return (float)sqrt(
|
||||
(v.x * v.x) +
|
||||
(v.y * v.y)
|
||||
);
|
||||
}
|
||||
|
||||
static fixed vector2fp_length(VECTOR2FP v) {
|
||||
return fix_sqrt(
|
||||
fix_mul(v.x, v.x) +
|
||||
fix_mul(v.y, v.y)
|
||||
);
|
||||
}
|
||||
|
||||
static int vector2i_lengthsq(VECTOR2I v) {
|
||||
return
|
||||
(v.x * v.x) +
|
||||
(v.y * v.y);
|
||||
}
|
||||
|
||||
static float vector2f_lengthsq(VECTOR2F v) {
|
||||
return
|
||||
(v.x * v.x) +
|
||||
(v.y * v.y);
|
||||
}
|
||||
|
||||
static fixed vector2fp_lengthsq(VECTOR2FP v) {
|
||||
return
|
||||
fix_mul(v.x, v.x) +
|
||||
fix_mul(v.y, v.y);
|
||||
}
|
||||
|
||||
static VECTOR2F vector2f_normalize(VECTOR2F v) {
|
||||
float inverse_length;
|
||||
VECTOR2F result;
|
||||
|
||||
inverse_length = 1.0f / vector2f_length(v);
|
||||
result.x = v.x * inverse_length;
|
||||
result.y = v.y * inverse_length;
|
||||
return result;
|
||||
}
|
||||
|
||||
static VECTOR2FP vector2fp_normalize(VECTOR2FP v) {
|
||||
fixed inverse_length;
|
||||
VECTOR2FP result;
|
||||
|
||||
inverse_length = fix_div(FP_1, vector2fp_length(v));
|
||||
result.x = fix_mul(v.x, inverse_length);
|
||||
result.y = fix_mul(v.y, inverse_length);
|
||||
return result;
|
||||
}
|
||||
|
||||
static VECTOR2F vector2f_set_length(VECTOR2F v, float length) {
|
||||
float scale_factor;
|
||||
VECTOR2F result;
|
||||
|
||||
scale_factor = length / vector2f_length(v);
|
||||
result.x = v.x * scale_factor;
|
||||
result.y = v.y * scale_factor;
|
||||
return result;
|
||||
}
|
||||
|
||||
static VECTOR2FP vector2fp_set_length(VECTOR2FP v, fixed length) {
|
||||
fixed scale_factor;
|
||||
VECTOR2FP result;
|
||||
|
||||
scale_factor = fix_div(length, vector2fp_length(v));
|
||||
result.x = fix_mul(v.x, scale_factor);
|
||||
result.y = fix_mul(v.y, scale_factor);
|
||||
return result;
|
||||
}
|
||||
|
||||
static VECTOR2I vector2i_lerp(VECTOR2I a, VECTOR2I b, float lerp) {
|
||||
VECTOR2I result;
|
||||
result.x = a.x + (b.x - a.x) * lerp;
|
||||
result.y = a.y + (b.y - a.y) * lerp;
|
||||
return result;
|
||||
}
|
||||
|
||||
static VECTOR2F vector2f_lerp(VECTOR2F a, VECTOR2F b, float lerp) {
|
||||
VECTOR2F result;
|
||||
result.x = a.x + (b.x - a.x) * lerp;
|
||||
result.y = a.y + (b.y - a.y) * lerp;
|
||||
return result;
|
||||
}
|
||||
|
||||
static VECTOR2FP vector2fp_lerp(VECTOR2FP a, VECTOR2FP b, fixed lerp) {
|
||||
VECTOR2FP result;
|
||||
result.x = a.x + fix_mul((b.x - a.x), lerp);
|
||||
result.y = a.y + fix_mul((b.y - a.y), lerp);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
151
GFX.C
151
GFX.C
|
@ -1,151 +0,0 @@
|
|||
#include "gfx.h"
|
||||
#include "blit.h"
|
||||
#include "util.h"
|
||||
#include "internal.h"
|
||||
#include "error.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <dpmi.h>
|
||||
#include <pc.h>
|
||||
|
||||
static boolean _initialized = FALSE;
|
||||
|
||||
SURFACE *screen = NULL;
|
||||
|
||||
static SURFACE* surface_create_internal(int width, int height, byte *pixels) {
|
||||
SURFACE *surface = malloc(sizeof(SURFACE));
|
||||
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
surface->clip_region = rect(0, 0, width, height);
|
||||
|
||||
if (pixels != NULL) {
|
||||
surface->aliased = TRUE;
|
||||
surface->pixels = pixels;
|
||||
} else {
|
||||
surface->aliased = FALSE;
|
||||
surface->pixels = malloc(width * height);
|
||||
memset(surface->pixels, 0, width * height);
|
||||
}
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
boolean video_init(void) {
|
||||
__dpmi_regs regs;
|
||||
void *framebuffer;
|
||||
|
||||
if (_initialized) {
|
||||
dgl_set_error(DGL_VIDEO_ALREADY_INITIALIZED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memset(®s, 0, sizeof(__dpmi_regs));
|
||||
regs.h.ah = 0x00;
|
||||
regs.h.al = 0x13;
|
||||
if (__dpmi_int(0x10, ®s)) {
|
||||
dgl_set_error(DGL_VIDEO_MODE_13H_INIT_FAILURE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
framebuffer = map_dos_memory(0xa0000);
|
||||
screen = surface_create_internal(320, 200, framebuffer);
|
||||
surface_clear(screen, 0);
|
||||
|
||||
_initialized = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
boolean video_shutdown(void) {
|
||||
__dpmi_regs regs;
|
||||
|
||||
if (!_initialized)
|
||||
return TRUE; // don't care
|
||||
|
||||
memset(®s, 0, sizeof(__dpmi_regs));
|
||||
regs.h.ah = 0x00;
|
||||
regs.h.al = 0x03;
|
||||
if (__dpmi_int(0x10, ®s)) {
|
||||
dgl_set_error(DGL_VIDEO_TEXT_MODE_INIT_FAILURE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
surface_free(screen);
|
||||
screen = NULL;
|
||||
|
||||
_initialized = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
boolean video_is_initialized(void) {
|
||||
return _initialized;
|
||||
}
|
||||
|
||||
void video_wait_vsync(void) {
|
||||
do {} while (inportb(0x3da) & 0x8);
|
||||
do {} while (!(inportb(0x3da) & 0x8));
|
||||
}
|
||||
|
||||
void video_set_color(ubyte color, ubyte r, ubyte g, ubyte b) {
|
||||
outportb(0x3c6, 0xff);
|
||||
outportb(0x3c8, color);
|
||||
outportb(0x3c9, r);
|
||||
outportb(0x3c9, g);
|
||||
outportb(0x3c9, b);
|
||||
}
|
||||
|
||||
void video_get_color(ubyte color, ubyte *r, ubyte *g, ubyte *b) {
|
||||
outportb(0x3c6, 0xff);
|
||||
outportb(0x3c7, color);
|
||||
*r = inportb(0x3c9);
|
||||
*g = inportb(0x3c9);
|
||||
*b = inportb(0x3c9);
|
||||
}
|
||||
|
||||
void video_set_palette(const byte *palette) {
|
||||
int i = 0;
|
||||
for (i = 0; i < 256; ++i) {
|
||||
video_set_color(i, palette[0], palette[1], palette[2]);
|
||||
palette += 3;
|
||||
}
|
||||
}
|
||||
|
||||
void video_get_palette(byte *palette) {
|
||||
int i = 0;
|
||||
for (i = 0; i < 256; ++i) {
|
||||
video_get_color(i, palette, palette + 1, palette + 2);
|
||||
palette += 3;
|
||||
}
|
||||
}
|
||||
|
||||
SURFACE* surface_create(int width, int height) {
|
||||
return surface_create_internal(width, height, NULL);
|
||||
}
|
||||
|
||||
void surface_free(SURFACE *surface) {
|
||||
if (!surface)
|
||||
return;
|
||||
|
||||
if (!surface->aliased)
|
||||
free(surface->pixels);
|
||||
free(surface);
|
||||
}
|
||||
|
||||
void surface_clear(SURFACE *surface, int color) {
|
||||
int length = surface->width * surface->height;
|
||||
if (length % 4 == 0) {
|
||||
color *= 0x01010101;
|
||||
REP_STOSL(color, surface->pixels, length / 4);
|
||||
} else {
|
||||
memset(surface->pixels, color, surface->width * surface->height);
|
||||
}
|
||||
}
|
||||
|
||||
void surface_copy(const SURFACE *src, SURFACE *dest) {
|
||||
if (src->width == dest->width && src->height == dest->height) {
|
||||
memcpy(dest->pixels, src->pixels, src->width * src->height);
|
||||
} else {
|
||||
surface_blit(src, dest, 0, 0);
|
||||
}
|
||||
}
|
||||
|
47
GFX.H
47
GFX.H
|
@ -1,47 +0,0 @@
|
|||
#ifndef DGL_GFX_H_INCLUDED
|
||||
#define DGL_GFX_H_INCLUDED
|
||||
|
||||
#include "common.h"
|
||||
#include "rect.h"
|
||||
|
||||
typedef struct {
|
||||
int width;
|
||||
int height;
|
||||
byte *pixels;
|
||||
boolean aliased;
|
||||
RECT clip_region;
|
||||
} SURFACE;
|
||||
|
||||
extern SURFACE *screen;
|
||||
|
||||
boolean video_init(void);
|
||||
boolean video_shutdown(void);
|
||||
boolean video_is_initialized(void);
|
||||
|
||||
void video_wait_vsync(void);
|
||||
|
||||
void video_set_color(ubyte color, ubyte r, ubyte g, ubyte b);
|
||||
void video_get_color(ubyte color, ubyte *r, ubyte *g, ubyte *b);
|
||||
void video_set_palette(const byte *palette);
|
||||
void video_get_palette(byte *palette);
|
||||
|
||||
SURFACE* surface_create(int width, int height);
|
||||
void surface_free(SURFACE *surface);
|
||||
void surface_clear(SURFACE *surface, int color);
|
||||
void surface_copy(const SURFACE *src, SURFACE *dest);
|
||||
|
||||
static inline int surface_offset(const SURFACE *surface, int x, int y);
|
||||
static inline byte* surface_pointer(const SURFACE *surface, int x, int y);
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
static inline int surface_offset(const SURFACE *surface, int x, int y) {
|
||||
return surface->width * y + x;
|
||||
}
|
||||
|
||||
static inline byte* surface_pointer(const SURFACE *surface, int x, int y) {
|
||||
return surface->pixels + surface_offset(surface, x, y);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
36
INTERNAL.C
36
INTERNAL.C
|
@ -1,36 +0,0 @@
|
|||
#include "internal.h"
|
||||
#include <dpmi.h>
|
||||
#include <go32.h>
|
||||
#include <string.h>
|
||||
|
||||
boolean _install_irq(int irq,
|
||||
void* irq_handler,
|
||||
_go32_dpmi_seginfo* new_handler,
|
||||
_go32_dpmi_seginfo* old_handler) {
|
||||
memset((void*)new_handler, 0, sizeof(_go32_dpmi_seginfo));
|
||||
|
||||
if (_go32_dpmi_get_real_mode_interrupt_vector(irq, old_handler) != 0)
|
||||
return FALSE;
|
||||
|
||||
new_handler->pm_offset = (int)irq_handler;
|
||||
new_handler->pm_selector = _go32_my_cs();
|
||||
|
||||
if (_go32_dpmi_allocate_iret_wrapper(new_handler) != 0)
|
||||
return FALSE;
|
||||
if (_go32_dpmi_set_protected_mode_interrupt_vector(irq, new_handler) != 0)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
boolean _restore_irq(int irq,
|
||||
_go32_dpmi_seginfo* new_handler,
|
||||
_go32_dpmi_seginfo* old_handler) {
|
||||
if (_go32_dpmi_set_real_mode_interrupt_vector(irq, old_handler) != 0)
|
||||
return FALSE;
|
||||
if (_go32_dpmi_free_iret_wrapper(new_handler) != 0)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
60
INTERNAL.H
60
INTERNAL.H
|
@ -1,60 +0,0 @@
|
|||
#ifndef DGL_INTERNAL_H_INCLUDED
|
||||
#define DGL_INTERNAL_H_INCLUDED
|
||||
|
||||
#include "common.h"
|
||||
#include <dpmi.h>
|
||||
|
||||
#define END_OF_FUNCTION(x) void x##_end() {}
|
||||
#define LOCK_VARIABLE(x) _go32_dpmi_lock_data((void*)&x, sizeof(x))
|
||||
#define LOCK_MEMORY(ptr, len) _go32_dpmi_lock_data((void*)(ptr), (len))
|
||||
#define LOCK_FUNCTION(x) _go32_dpmi_lock_code(x, (long)x##_end - (long)x)
|
||||
|
||||
static inline void _enable_interrupts(void) {
|
||||
asm volatile ("sti");
|
||||
}
|
||||
static inline void _disable_interrupts(void) {
|
||||
asm volatile ("cli");
|
||||
}
|
||||
|
||||
boolean _install_irq(int irq,
|
||||
void* irq_handler,
|
||||
_go32_dpmi_seginfo* new_handler,
|
||||
_go32_dpmi_seginfo* old_handler);
|
||||
boolean _restore_irq(int irq,
|
||||
_go32_dpmi_seginfo* new_handler,
|
||||
_go32_dpmi_seginfo* old_handler);
|
||||
|
||||
#define REP_MOVSL(src, dest, num_dwords) \
|
||||
__asm__ __volatile__ ( \
|
||||
"cld\n\t" \
|
||||
"rep\n\t" \
|
||||
"movsl" \
|
||||
: : "S" (src), "D" (dest), "c" (num_dwords) \
|
||||
: "%ecx", "%esi", "%edi" )
|
||||
|
||||
#define REP_MOVSB(src, dest, num_bytes) \
|
||||
__asm__ __volatile__ ( \
|
||||
"cld\n\t" \
|
||||
"rep\n\t" \
|
||||
"movsb" \
|
||||
: : "S" (src), "D" (dest), "c" (num_bytes) \
|
||||
: "%ecx", "%esi", "%edi" )
|
||||
|
||||
#define REP_STOSL(value, dest, num_dwords) \
|
||||
__asm__ __volatile__ ( \
|
||||
"cld\n\t" \
|
||||
"rep\n\t" \
|
||||
"stosl" \
|
||||
: : "a" (value), "D" (dest), "c" (num_dwords) \
|
||||
: "%ecx", "%edi" )
|
||||
|
||||
#define REP_STOSB(value, dest, num_bytes) \
|
||||
__asm__ __volatile__ ( \
|
||||
"cld\n\t" \
|
||||
"rep\n\t" \
|
||||
"stosb" \
|
||||
: : "a" (value), "D" (dest), "c" (num_bytes) \
|
||||
: "%ecx", "%edi" )
|
||||
|
||||
#endif
|
||||
|
BIN
LIBDGL.GDT
BIN
LIBDGL.GDT
Binary file not shown.
BIN
LIBDGL.GPR
BIN
LIBDGL.GPR
Binary file not shown.
80
MAKEFILE
Normal file
80
MAKEFILE
Normal file
|
@ -0,0 +1,80 @@
|
|||
target_config = release
|
||||
|
||||
target_name = dgl
|
||||
|
||||
object_files = &
|
||||
dglblit.obj &
|
||||
dglblita.obj &
|
||||
dglclip.obj &
|
||||
dgl.obj &
|
||||
dgldraw.obj &
|
||||
dgldrawa.obj &
|
||||
dglgfx.obj &
|
||||
dglpal.obj &
|
||||
dglkbrd.obj &
|
||||
dglmath.obj &
|
||||
dglfixp.obj &
|
||||
dglmouse.obj &
|
||||
dglpcx.obj &
|
||||
dglutil.obj
|
||||
|
||||
test_object_files = test.obj
|
||||
|
||||
cc_flags_debug = /d2 /zp4 /5r /fp3 /j
|
||||
cc_flags_release = /d1+ /zp4 /5r /fp3 /onatx /oe=40 /j
|
||||
cc_flags = /mf $(cc_flags_$(target_config))
|
||||
|
||||
link_flags_debug = debug all
|
||||
link_flags_release = debug all
|
||||
link_flags = $(link_flags_$(target_config))
|
||||
|
||||
asm_flags_debug = /zi
|
||||
asm_flags_release = /zi
|
||||
asm_flags = /m /ml $(asm_flags_$(target_config))
|
||||
|
||||
.c.obj: .AUTODEPEND
|
||||
wcc386 $[. /zq $(cc_flags)
|
||||
|
||||
.asm.obj: .AUTODEPEND
|
||||
tasm $[. /t $(asm_flags)
|
||||
|
||||
$(target_name).lnk: $(object_files) $(test_object_files)
|
||||
%create $^@
|
||||
%append $^@ NAME $(target_name).exe
|
||||
%append $^@ SYSTEM DOS4G
|
||||
%append $^@ OPTION QUIET
|
||||
@for %i in ($(object_files)) do %append $^@ FILE %i
|
||||
@for %i in ($(test_object_files)) do %append $^@ FILE %i
|
||||
|
||||
$(target_name).exe: $(object_files) $(test_object_files) $(target_name).lnk
|
||||
wlink $(link_flags) @$(target_name).lnk
|
||||
|
||||
$(target_name).lbc: $(object_files)
|
||||
%create $^@
|
||||
@for %i in ($(object_files)) do %append $^@ +%i
|
||||
|
||||
$(target_name).lib: $(object_files) $(target_name).lbc
|
||||
wlib /n /q /b $(target_name).lib @$(target_name).lbc
|
||||
|
||||
clean : .SYMBOLIC
|
||||
del *.obj
|
||||
del *.err
|
||||
del $(target_name).exe
|
||||
del $(target_name).lnk
|
||||
del $(target_name).lbc
|
||||
|
||||
.NOCHECK
|
||||
build : $(target_name).lib
|
||||
#build : $(target_name).exe
|
||||
|
||||
.NOCHECK
|
||||
library : $(target_name).lib
|
||||
|
||||
.NOCHECK
|
||||
run : $(target_name).exe
|
||||
$(target_name).exe
|
||||
|
||||
.NOCHECK
|
||||
debug : $(target_name).exe
|
||||
wd /swap /trap=rsi $(target_name).exe
|
||||
|
188
MOUSE.C
188
MOUSE.C
|
@ -1,188 +0,0 @@
|
|||
#include "mouse.h"
|
||||
#include "internal.h"
|
||||
#include "error.h"
|
||||
#include <string.h>
|
||||
#include <go32.h>
|
||||
|
||||
static boolean _installed = FALSE;
|
||||
static boolean _has_mouse = FALSE;
|
||||
|
||||
volatile int mouse_x;
|
||||
volatile int mouse_y;
|
||||
volatile int mouse_buttons;
|
||||
volatile int mouse_delta_x;
|
||||
volatile int mouse_delta_y;
|
||||
|
||||
__dpmi_regs _mouse_regs;
|
||||
_go32_dpmi_seginfo _mouse_seg_info;
|
||||
|
||||
static void reset_mouse_state(void) {
|
||||
mouse_x = 0;
|
||||
mouse_y = 0;
|
||||
mouse_buttons = 0;
|
||||
mouse_delta_x = 0;
|
||||
mouse_delta_y = 0;
|
||||
}
|
||||
|
||||
static boolean init_mouse_driver(void) {
|
||||
__dpmi_regs regs;
|
||||
|
||||
memset(®s, 0, sizeof(__dpmi_regs));
|
||||
regs.x.ax = 0x00;
|
||||
__dpmi_int(0x33, ®s);
|
||||
|
||||
return (regs.x.ax != 0);
|
||||
}
|
||||
|
||||
static void update_mouse_state(void) {
|
||||
__dpmi_regs regs;
|
||||
|
||||
memset(®s, 0, sizeof(__dpmi_regs));
|
||||
regs.x.ax = 0x03;
|
||||
__dpmi_int(0x33, ®s);
|
||||
mouse_x = (regs.x.cx / 2);
|
||||
mouse_y = regs.x.dx;
|
||||
mouse_buttons = regs.x.bx;
|
||||
mouse_delta_x = 0;
|
||||
mouse_delta_y = 0;
|
||||
}
|
||||
|
||||
void mouse_int_handler(__dpmi_regs* regs) {
|
||||
mouse_delta_x = (regs->x.cx / 2) - mouse_x;
|
||||
mouse_delta_y = regs->x.dx - mouse_y;
|
||||
mouse_x = (regs->x.cx / 2);
|
||||
mouse_y = regs->x.dx;
|
||||
mouse_buttons = regs->x.bx;
|
||||
}
|
||||
END_OF_FUNCTION(mouse_int_handler)
|
||||
|
||||
boolean mouse_init(void) {
|
||||
__dpmi_regs regs;
|
||||
|
||||
if (_installed) {
|
||||
dgl_set_error(DGL_MOUSE_ALREADY_INITIALIZED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
reset_mouse_state();
|
||||
|
||||
_has_mouse = init_mouse_driver();
|
||||
if (!_has_mouse) {
|
||||
_installed = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
LOCK_FUNCTION(mouse_int_handler);
|
||||
LOCK_VARIABLE(_mouse_regs);
|
||||
LOCK_VARIABLE(_mouse_seg_info);
|
||||
LOCK_VARIABLE(mouse_x);
|
||||
LOCK_VARIABLE(mouse_y);
|
||||
LOCK_VARIABLE(mouse_buttons);
|
||||
LOCK_VARIABLE(mouse_delta_x);
|
||||
LOCK_VARIABLE(mouse_delta_y);
|
||||
|
||||
memset(&_mouse_regs, 0, sizeof(__dpmi_regs));
|
||||
memset(&_mouse_seg_info, 0, sizeof(_go32_dpmi_seginfo));
|
||||
|
||||
_mouse_seg_info.pm_offset = (int)mouse_int_handler;
|
||||
_mouse_seg_info.pm_selector = _go32_my_cs();
|
||||
if (_go32_dpmi_allocate_real_mode_callback_retf(&_mouse_seg_info, &_mouse_regs) != 0) {
|
||||
dgl_set_error(DGL_MOUSE_ALLOCATE_CALLBACK_FAILURE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
update_mouse_state();
|
||||
|
||||
memset(®s, 0, sizeof(__dpmi_regs));
|
||||
regs.x.ax = 0x0c;
|
||||
regs.x.cx = 0x7f;
|
||||
regs.x.dx = _mouse_seg_info.rm_offset;
|
||||
regs.x.es = _mouse_seg_info.rm_segment;
|
||||
if (__dpmi_int(0x33, ®s) != 0) {
|
||||
dgl_set_error(DGL_MOUSE_INT_CALLBACK_SET_FAILURE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_installed = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
boolean mouse_shutdown(void) {
|
||||
__dpmi_regs regs;
|
||||
|
||||
if (!_installed)
|
||||
return TRUE; // don't care
|
||||
|
||||
if (!_has_mouse) {
|
||||
_installed = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
memset(®s, 0, sizeof(__dpmi_regs));
|
||||
regs.x.ax = 0x0c;
|
||||
regs.x.cx = 0;
|
||||
regs.x.dx = 0;
|
||||
regs.x.es = 0;
|
||||
if (__dpmi_int(0x33, ®s) != 0) {
|
||||
dgl_set_error(DGL_MOUSE_INT_CALLBACK_RESTORE_FAILURE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (_go32_dpmi_free_real_mode_callback(&_mouse_seg_info) != 0)
|
||||
dgl_set_error(DGL_MOUSE_FREE_CALLBACK_FAILURE);
|
||||
|
||||
reset_mouse_state();
|
||||
|
||||
_installed = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
boolean mouse_is_initialized(void) {
|
||||
return _installed;
|
||||
}
|
||||
|
||||
boolean mouse_is_present(void) {
|
||||
return _has_mouse;
|
||||
}
|
||||
|
||||
void mouse_show(void) {
|
||||
__dpmi_regs regs;
|
||||
|
||||
if (!_has_mouse)
|
||||
return;
|
||||
|
||||
memset(®s, 0, sizeof(__dpmi_regs));
|
||||
regs.x.ax = 0x01;
|
||||
__dpmi_int(0x33, ®s);
|
||||
}
|
||||
|
||||
void mouse_hide(void) {
|
||||
__dpmi_regs regs;
|
||||
|
||||
if (!_has_mouse)
|
||||
return;
|
||||
|
||||
memset(®s, 0, sizeof(__dpmi_regs));
|
||||
regs.x.ax = 0x02;
|
||||
__dpmi_int(0x33, ®s);
|
||||
}
|
||||
|
||||
void mouse_set_bounds(int min_x, int min_y, int max_x, int max_y) {
|
||||
__dpmi_regs regs;
|
||||
|
||||
if (!_has_mouse)
|
||||
return;
|
||||
|
||||
memset(®s, 0, sizeof(__dpmi_regs));
|
||||
|
||||
regs.x.ax = 0x07;
|
||||
regs.x.cx = min_x;
|
||||
regs.x.dx = max_x;
|
||||
__dpmi_int(0x33, ®s);
|
||||
|
||||
regs.x.ax = 0x08;
|
||||
regs.x.cx = min_y;
|
||||
regs.x.dx = max_y;
|
||||
__dpmi_int(0x33, ®s);
|
||||
}
|
||||
|
37
UTIL.C
37
UTIL.C
|
@ -1,37 +0,0 @@
|
|||
#include "util.h"
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <sys/nearptr.h>
|
||||
|
||||
#define SYS_CLOCKS_PER_SEC (1000.0f / 55.0f)
|
||||
|
||||
void* map_dos_memory(long physical_addr) {
|
||||
return (void*)(__djgpp_conventional_base + physical_addr);
|
||||
}
|
||||
|
||||
int sys_clock() {
|
||||
//return *((int*)(map_dos_memory(0x046c)));
|
||||
return (int)clock();
|
||||
}
|
||||
|
||||
int sys_ticks() {
|
||||
return (int)uclock();
|
||||
}
|
||||
|
||||
float clock_ticks_to_seconds(int clocks) {
|
||||
//return clocks / SYS_CLOCKS_PER_SEC;
|
||||
return clocks / (float)CLOCKS_PER_SEC;
|
||||
}
|
||||
|
||||
float ticks_to_seconds(int ticks) {
|
||||
return (float)ticks / UCLOCKS_PER_SEC;
|
||||
}
|
||||
|
||||
int rnd_int(int low, int high) {
|
||||
return rand() % ((high - low) + 1) + low;
|
||||
}
|
||||
|
||||
float rnd_float(float low, float high) {
|
||||
return low + (rand() / (float)RAND_MAX) * (high - low);
|
||||
}
|
||||
|
26
UTIL.H
26
UTIL.H
|
@ -1,26 +0,0 @@
|
|||
#ifndef DGL_UTIL_H_INCLUDED
|
||||
#define DGL_UTIL_H_INCLUDED
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define SWAP(type, a, b) \
|
||||
do { \
|
||||
type __tmp = a; \
|
||||
a = b; \
|
||||
b = __tmp; \
|
||||
} while (0)
|
||||
|
||||
#define SIGN(x) (((x) < 0) ? -1 : (((x) > 0) ? 1 : 0))
|
||||
|
||||
void* map_dos_memory(long physical_addr);
|
||||
|
||||
int sys_clock();
|
||||
int sys_ticks();
|
||||
float clock_ticks_to_seconds(int clocks);
|
||||
float ticks_to_seconds(int ticks);
|
||||
|
||||
int rnd_int(int low, int high);
|
||||
float rnd_float(float low, float high);
|
||||
|
||||
#endif
|
||||
|
284
VECTOR2.H
284
VECTOR2.H
|
@ -1,284 +0,0 @@
|
|||
#ifndef DGL_VECTOR2_H_INCLUDED
|
||||
#define DGL_VECTOR2_H_INCLUDED
|
||||
|
||||
#include <math.h>
|
||||
#include "common.h"
|
||||
|
||||
typedef struct {
|
||||
int x;
|
||||
int y;
|
||||
} VECTOR2I;
|
||||
|
||||
static inline VECTOR2I vector2i(int x, int y);
|
||||
static inline void vector2i_set(VECTOR2I *v, int x, int y);
|
||||
static inline boolean vector2i_equals(VECTOR2I a, VECTOR2I b);
|
||||
static inline VECTOR2I vector2i_add(VECTOR2I a, VECTOR2I b);
|
||||
static inline VECTOR2I vector2i_sub(VECTOR2I a, VECTOR2I b);
|
||||
static inline VECTOR2I vector2i_mul(VECTOR2I a, VECTOR2I b);
|
||||
static inline VECTOR2I vector2i_muls(VECTOR2I v, int n);
|
||||
static inline VECTOR2I vector2i_div(VECTOR2I a, VECTOR2I b);
|
||||
static inline VECTOR2I vector2i_divs(VECTOR2I v, int n);
|
||||
static inline int vector2i_distance(VECTOR2I a, VECTOR2I b);
|
||||
static inline int vector2i_distancesq(VECTOR2I a, VECTOR2I b);
|
||||
static inline int vector2i_dot(VECTOR2I a, VECTOR2I b);
|
||||
static inline int vector2i_length(VECTOR2I v);
|
||||
static inline int vector2i_lengthsq(VECTOR2I v);
|
||||
static inline VECTOR2I vector2i_lerp(VECTOR2I a, VECTOR2I b, float lerp);
|
||||
|
||||
#define ZERO_VECTOR2I vector2i(0, 0)
|
||||
#define UP_VECTOR2I vector2i(0, -1);
|
||||
#define DOWN_VECTOR2I vector2i(0, 1);
|
||||
#define LEFT_VECTOR2I vector2i(-1, 0);
|
||||
#define RIGHT_VECTOR2I vector2i(1, 0);
|
||||
#define UNIT_X_VECTOR2I vector2i(1, 0);
|
||||
#define UNIT_Y_VECTOR2I vector2i(0, 1);
|
||||
|
||||
typedef struct {
|
||||
float x;
|
||||
float y;
|
||||
} VECTOR2F;
|
||||
|
||||
static inline VECTOR2F vector2f(float x, float y);
|
||||
static inline void vector2f_set(VECTOR2F *v, float x, float y);
|
||||
static inline boolean vector2f_equals(VECTOR2F a, VECTOR2F b);
|
||||
static inline VECTOR2F vector2f_add(VECTOR2F a, VECTOR2F b);
|
||||
static inline VECTOR2F vector2f_sub(VECTOR2F a, VECTOR2F b);
|
||||
static inline VECTOR2F vector2f_mul(VECTOR2F a, VECTOR2F b);
|
||||
static inline VECTOR2F vector2f_muls(VECTOR2F v, float n);
|
||||
static inline VECTOR2F vector2f_div(VECTOR2F a, VECTOR2F b);
|
||||
static inline VECTOR2F vector2f_divs(VECTOR2F v, float n);
|
||||
static inline float vector2f_distance(VECTOR2F a, VECTOR2F b);
|
||||
static inline float vector2f_distancesq(VECTOR2F a, VECTOR2F b);
|
||||
static inline float vector2f_dot(VECTOR2F a, VECTOR2F b);
|
||||
static inline float vector2f_length(VECTOR2F v);
|
||||
static inline float vector2f_lengthsq(VECTOR2F v);
|
||||
static inline VECTOR2F vector2f_normalize(VECTOR2F v);
|
||||
static inline VECTOR2F vector2f_set_length(VECTOR2F v, float length);
|
||||
static inline VECTOR2F vector2f_lerp(VECTOR2F a, VECTOR2F b, float lerp);
|
||||
|
||||
#define ZERO_VECTOR2F vector2f(0.0f, 0.0f)
|
||||
#define UP_VECTOR2F vector2f(0.0f, -1.0f);
|
||||
#define DOWN_VECTOR2F vector2f(0.0f, 1.0f);
|
||||
#define LEFT_VECTOR2F vector2f(-1.0f, 0.0f);
|
||||
#define RIGHT_VECTOR2F vector2f(1.0f, 0.0f);
|
||||
#define UNIT_X_VECTOR2F vector2f(1.0f, 0.0f);
|
||||
#define UNIT_Y_VECTOR2F vector2f(0.0f, 1.0f);
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
static inline VECTOR2I vector2i(int x, int y) {
|
||||
VECTOR2I v;
|
||||
v.x = x;
|
||||
v.y = y;
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline VECTOR2F vector2f(float x, float y) {
|
||||
VECTOR2F v;
|
||||
v.x = x;
|
||||
v.y = y;
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline void vector2i_set(VECTOR2I *v, int x, int y) {
|
||||
v->x = x;
|
||||
v->y = y;
|
||||
}
|
||||
|
||||
static inline void vector2f_set(VECTOR2F *v, float x, float y) {
|
||||
v->x = x;
|
||||
v->y = y;
|
||||
}
|
||||
|
||||
static inline boolean vector2i_equals(VECTOR2I a, VECTOR2I b) {
|
||||
return (a.x == b.x && a.y == b.y);
|
||||
}
|
||||
|
||||
static inline boolean vector2f_equals(VECTOR2F a, VECTOR2F b) {
|
||||
return (a.x == b.x && a.y == b.y);
|
||||
}
|
||||
|
||||
static inline VECTOR2I vector2i_add(VECTOR2I a, VECTOR2I b) {
|
||||
VECTOR2I result;
|
||||
result.x = a.x + b.x;
|
||||
result.y = a.y + b.y;
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline VECTOR2F vector2f_add(VECTOR2F a, VECTOR2F b) {
|
||||
VECTOR2F result;
|
||||
result.x = a.x + b.x;
|
||||
result.y = a.y + b.y;
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline VECTOR2I vector2i_sub(VECTOR2I a, VECTOR2I b) {
|
||||
VECTOR2I result;
|
||||
result.x = a.x - b.x;
|
||||
result.y = a.y - b.y;
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline VECTOR2F vector2f_sub(VECTOR2F a, VECTOR2F b) {
|
||||
VECTOR2F result;
|
||||
result.x = a.x - b.x;
|
||||
result.y = a.y - b.y;
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline VECTOR2I vector2i_mul(VECTOR2I a, VECTOR2I b) {
|
||||
VECTOR2I result;
|
||||
result.x = a.x * b.x;
|
||||
result.y = a.y * b.y;
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline VECTOR2F vector2f_mul(VECTOR2F a, VECTOR2F b) {
|
||||
VECTOR2F result;
|
||||
result.x = a.x * b.x;
|
||||
result.y = a.y * b.y;
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline VECTOR2I vector2i_muls(VECTOR2I v, int n) {
|
||||
VECTOR2I result;
|
||||
result.x = v.x * n;
|
||||
result.y = v.y * n;
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline VECTOR2F vector2f_muls(VECTOR2F v, float n) {
|
||||
VECTOR2F result;
|
||||
result.x = v.x * n;
|
||||
result.y = v.y * n;
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline VECTOR2I vector2i_div(VECTOR2I a, VECTOR2I b) {
|
||||
VECTOR2I result;
|
||||
result.x = a.x / b.x;
|
||||
result.y = a.y / b.y;
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline VECTOR2F vector2f_div(VECTOR2F a, VECTOR2F b) {
|
||||
VECTOR2F result;
|
||||
result.x = a.x / b.x;
|
||||
result.y = a.y / b.y;
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline VECTOR2I vector2i_divs(VECTOR2I v, int n) {
|
||||
VECTOR2I result;
|
||||
result.x = v.x / n;
|
||||
result.y = v.y / n;
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline VECTOR2F vector2f_divs(VECTOR2F v, float n) {
|
||||
VECTOR2F result;
|
||||
result.x = v.x / n;
|
||||
result.y = v.y / n;
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline int vector2i_distance(VECTOR2I a, VECTOR2I b) {
|
||||
return (int)sqrt(
|
||||
((b.x - a.x) * (b.x - a.x)) +
|
||||
((b.y - a.y) * (b.y - a.y))
|
||||
);
|
||||
}
|
||||
|
||||
static inline float vector2f_distance(VECTOR2F a, VECTOR2F b) {
|
||||
return (float)sqrt(
|
||||
((b.x - a.x) * (b.x - a.x)) +
|
||||
((b.y - a.y) * (b.y - a.y))
|
||||
);
|
||||
}
|
||||
|
||||
static inline int vector2i_distancesq(VECTOR2I a, VECTOR2I b) {
|
||||
return
|
||||
((b.x - a.x) * (b.x - a.x)) +
|
||||
((b.y - a.y) * (b.y - a.y));
|
||||
}
|
||||
|
||||
static inline float vector2f_distancesq(VECTOR2F a, VECTOR2F b) {
|
||||
return
|
||||
((b.x - a.x) * (b.x - a.x)) +
|
||||
((b.y - a.y) * (b.y - a.y));
|
||||
}
|
||||
|
||||
static inline int vector2i_dot(VECTOR2I a, VECTOR2I b) {
|
||||
return
|
||||
(a.x * b.x) +
|
||||
(a.y * b.y);
|
||||
}
|
||||
|
||||
static inline float vector2f_dot(VECTOR2F a, VECTOR2F b) {
|
||||
return
|
||||
(a.x * b.x) +
|
||||
(a.y * b.y);
|
||||
}
|
||||
|
||||
static inline int vector2i_length(VECTOR2I v) {
|
||||
return sqrt(
|
||||
(v.x * v.x) +
|
||||
(v.y * v.y)
|
||||
);
|
||||
}
|
||||
|
||||
static inline float vector2f_length(VECTOR2F v) {
|
||||
return (float)sqrt(
|
||||
(v.x * v.x) +
|
||||
(v.y * v.y)
|
||||
);
|
||||
}
|
||||
|
||||
static inline int vector2i_lengthsq(VECTOR2I v) {
|
||||
return
|
||||
(v.x * v.x) +
|
||||
(v.y * v.y);
|
||||
}
|
||||
|
||||
static inline float vector2f_lengthsq(VECTOR2F v) {
|
||||
return
|
||||
(v.x * v.x) +
|
||||
(v.y * v.y);
|
||||
}
|
||||
|
||||
static inline VECTOR2F vector2f_normalize(VECTOR2F v) {
|
||||
float inverse_length;
|
||||
VECTOR2F result;
|
||||
|
||||
inverse_length = 1.0f / vector2f_length(v);
|
||||
result.x = v.x * inverse_length;
|
||||
result.y = v.y * inverse_length;
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline VECTOR2F vector2f_set_length(VECTOR2F v, float length) {
|
||||
float scale_factor;
|
||||
VECTOR2F result;
|
||||
|
||||
scale_factor = length / vector2f_length(v);
|
||||
result.x = v.x * scale_factor;
|
||||
result.y = v.y * scale_factor;
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline VECTOR2I vector2i_lerp(VECTOR2I a, VECTOR2I b, float lerp) {
|
||||
VECTOR2I result;
|
||||
result.x = a.x + (b.x - a.x) * lerp;
|
||||
result.y = a.y + (b.y - a.y) * lerp;
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline VECTOR2F vector2f_lerp(VECTOR2F a, VECTOR2F b, float lerp) {
|
||||
VECTOR2F result;
|
||||
result.x = a.x + (b.x - a.x) * lerp;
|
||||
result.y = a.y + (b.y - a.y) * lerp;
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in a new issue