many updates. moved project over to watcom

This commit is contained in:
Gered 2018-04-28 11:30:53 -04:00
parent e5415c977c
commit 123d3b8256
44 changed files with 3497 additions and 1292 deletions

68
DGL.C
View file

@ -1,68 +1,22 @@
#include "dgl.h" #include "dgl.h"
#include "keyboard.h" #include "dglkbrd.h"
#include "mouse.h" #include "dglmouse.h"
#include "gfx.h" #include "dglgfx.h"
#include "util.h" #include "dglutil.h"
#include <stdlib.h> #include <stdlib.h>
#include <go32.h>
#include <sys/nearptr.h>
static boolean _initialized = FALSE;
static DGL_ERROR _last_error = DGL_NONE; 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) { 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) { const char* dgl_last_error_message(void) {
switch (_last_error) { switch (_last_error) {
case DGL_NONE: case DGL_NONE:
return "No error."; return "";
case DGL_ALREADY_INIT: case DGL_ALREADY_INIT:
return "DGL is already initialized."; return "DGL is already initialized.";
case DGL_NEARPTR_ENABLE_FAILURE: case DGL_NEARPTR_ENABLE_FAILURE:
@ -104,3 +58,9 @@ void dgl_set_error(DGL_ERROR error) {
_last_error = error; _last_error = error;
} }
void dgl_init(void) {
atexit(mouse_shutdown);
atexit(keyboard_shutdown);
atexit(video_shutdown);
}

33
DGL.H
View file

@ -1,24 +1,25 @@
#ifndef DGL_DGL_H_INCLUDED #ifndef DGL_DGL_H_INCLUDED
#define DGL_DGL_H_INCLUDED #define DGL_DGL_H_INCLUDED
#include "common.h" #include "dglcmn.h"
#include "error.h" #include "dglerror.h"
#include "keyboard.h" #include "dglkbrd.h"
#include "mouse.h" #include "dglmouse.h"
#include "gfx.h" #include "dglgfx.h"
#include "clipping.h" #include "dglpal.h"
#include "draw.h" #include "dglclip.h"
#include "blit.h" #include "dgldraw.h"
#include "mathext.h" #include "dglblit.h"
#include "rect.h" #include "dglmath.h"
#include "vector2.h" #include "dglfixp.h"
#include "matrix33.h" #include "dglrect.h"
#include "util.h" #include "dglvec2.h"
#include "pcx.h" #include "dglmtx33.h"
#include "dglutil.h"
#include "dglpcx.h"
boolean dgl_init(void); void dgl_init(void);
boolean dgl_shutdown(void);
#endif #endif

View file

@ -1,8 +1,7 @@
#include "blit.h" #include "dglblit.h"
#include "clipping.h" #include "dglclip.h"
#include "internal.h"
static inline boolean clip_blit(const RECT *dest_clip_region, static boolean clip_blit(const RECT *dest_clip_region,
RECT *src_blit_region, RECT *src_blit_region,
int *dest_x, int *dest_x,
int *dest_y) { int *dest_y) {
@ -13,7 +12,7 @@ static inline boolean clip_blit(const RECT *dest_clip_region,
// off the left edge? // off the left edge?
if (*dest_x < dest_clip_region->x) { if (*dest_x < dest_clip_region->x) {
// completely off the left edge? // 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; return FALSE;
offset = src_blit_region->x - *dest_x; 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? // off the top edge?
if (*dest_y < dest_clip_region->y) { if (*dest_y < dest_clip_region->y) {
// completely off the top edge? // 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; return FALSE;
offset = dest_clip_region->y - *dest_y; offset = dest_clip_region->y - *dest_y;
@ -85,34 +84,31 @@ void surface_blit_region_f(const SURFACE *src,
int src_height, int src_height,
int dest_x, int dest_x,
int dest_y) { int dest_y) {
byte *psrc, *pdest; const byte *psrc;
int src_y_inc, dest_y_inc; byte *pdest;
int width; int lines;
int lines_left; int src_y_inc = src->width - src_width;
int num_dwords; int dest_y_inc = dest->width - src_width;
int width_4, width_remainder;
psrc = surface_pointer(src, src_x, src_y); psrc = (const byte*)surface_pointer(src, src_x, src_y);
src_y_inc = src->width; pdest = (byte*)surface_pointer(dest, dest_x, dest_y);
pdest = surface_pointer(dest, dest_x, dest_y); lines = src_height;
dest_y_inc = dest->width;
width = src_width; width_4 = src_width / 4;
lines_left = src_height; 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 { } else {
while (lines_left) { // width is <= 3
REP_MOVSB(psrc, pdest, width); direct_blit_r(width_remainder, lines, pdest, psrc, dest_y_inc, src_y_inc);
psrc += src_y_inc;
pdest += dest_y_inc;
--lines_left;
}
} }
} }
@ -144,61 +140,49 @@ void surface_blit_sprite_region_f(const SURFACE *src,
int src_height, int src_height,
int dest_x, int dest_x,
int dest_y) { int dest_y) {
byte *psrc, *pdest; const byte *psrc;
byte *pdest;
byte pixel; byte pixel;
int src_y_inc, dest_y_inc; int src_y_inc, dest_y_inc;
int width; int width, width_4, width_8, width_remainder;
int lines_left; int lines_left;
int x; 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; 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; dest_y_inc = dest->width;
width = src_width; width = src_width;
lines_left = src_height; lines_left = src_height;
// based on benchmarking on a DX2-66, there is VERY significant src_y_inc -= width;
// diminishing returns for loop unrolling beyond these sizes dest_y_inc -= width;
// (in fact, even the one for 8 is a very small gain over 4)
if (width % 8 == 0) { width_4 = width / 4;
while (lines_left) { width_remainder = width & 3;
for (x = 0; x < width; x += 8) {
if ((pixel = psrc[x + 0])) pdest[x + 0] = pixel; if (width_4 && !width_remainder) {
if ((pixel = psrc[x + 1])) pdest[x + 1] = pixel; if ((width_4 & 1) == 0) {
if ((pixel = psrc[x + 2])) pdest[x + 2] = pixel; // width is actually an even multiple of 8!
if ((pixel = psrc[x + 3])) pdest[x + 3] = pixel; direct_blit_sprite_8(width_4 / 2, lines_left, pdest, psrc, dest_y_inc, src_y_inc);
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;
}
} 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 { } else {
while (lines_left) { // width is a multiple of 4 (no remainder)
for (x = 0; x < width; ++x) { direct_blit_sprite_4(width_4, lines_left, pdest, psrc, dest_y_inc, src_y_inc);
if ((pixel = psrc[x]))
pdest[x] = pixel;
} }
psrc += src_y_inc;
pdest += dest_y_inc; } else if (width_4 && width_remainder) {
--lines_left; 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 {
// width is <= 3
direct_blit_sprite_r(width_remainder, lines_left, pdest, psrc, dest_y_inc, src_y_inc);
} }
} }

View file

@ -1,7 +1,8 @@
#ifndef DGL_BLIT_H_INCLUDED #ifndef DGL_DGLBLIT_H_INCLUDED
#define DGL_BLIT_H_INCLUDED #define DGL_DGLBLIT_H_INCLUDED
#include "gfx.h" #include "dglgfx.h"
#include "dglutil.h"
void surface_blit_region(const SURFACE *src, void surface_blit_region(const SURFACE *src,
SURFACE *dest, SURFACE *dest,
@ -21,8 +22,9 @@ void surface_blit_region_f(const SURFACE *src,
int dest_x, int dest_x,
int dest_y); int dest_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);
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);
void surface_blit_sprite_region(const SURFACE *src, void surface_blit_sprite_region(const SURFACE *src,
SURFACE *dest, SURFACE *dest,
@ -42,24 +44,34 @@ void surface_blit_sprite_region_f(const SURFACE *src,
int dest_x, int dest_x,
int dest_y); int dest_y);
static inline void surface_blit_sprite(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);
static inline void surface_blit_sprite_f(const SURFACE *src, SURFACE *dest, int x, int y); 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); 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); 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); 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); surface_blit_sprite_region_f(src, dest, 0, 0, src->width, src->height, x, y);
} }

535
DGLBLITA.ASM Normal file
View 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

View file

@ -1,8 +1,8 @@
#include "clipping.h" #include "dglclip.h"
#include "common.h" #include "dglcmn.h"
#include "mathext.h" #include "dglmath.h"
static inline boolean is_in_bounds(int clip_x, static boolean is_in_bounds(int clip_x,
int clip_y, int clip_y,
int clip_right, int clip_right,
int clip_bottom, int clip_bottom,

View file

@ -1,8 +1,8 @@
#ifndef DGL_CLIPPING_H_INCLUDED #ifndef DGL_DGLCLIP_H_INCLUDED
#define DGL_CLIPPING_H_INCLUDED #define DGL_DGLCLIP_H_INCLUDED
#include "common.h" #include "dglcmn.h"
#include "rect.h" #include "dglrect.h"
/* /*
* Determines if the given point lies within the clipping region. * Determines if the given point lies within the clipping region.

View file

@ -1,5 +1,5 @@
#ifndef DGL_COMMON_H_INCLUDED #ifndef DGL_DGLCMN_H_INCLUDED
#define DGL_COMMON_H_INCLUDED #define DGL_DGLCMN_H_INCLUDED
typedef int boolean; typedef int boolean;
@ -27,7 +27,7 @@ typedef unsigned int uint;
#define BIT_6 0x40 #define BIT_6 0x40
#define BIT_7 0x80 #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_SET(bit, x) ((x) |= (bit))
#define BIT_CLEAR(bit, x) ((x) &= ~(bit)) #define BIT_CLEAR(bit, x) ((x) &= ~(bit))
#define BIT_TOGGLE(bit, x) ((x) ^= (bit)) #define BIT_TOGGLE(bit, x) ((x) ^= (bit))

View file

@ -1,27 +1,36 @@
#include "draw.h" #include "dgldraw.h"
#include "gfx.h" #include "dglgfx.h"
#include "mathext.h" #include "dglmath.h"
#include "util.h" #include "dglutil.h"
#include "internal.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
#include <string.h>
static char printf_buffer[1024]; static char printf_buffer[1024];
void surface_hline_f(SURFACE *surface, int x1, int x2, int y, int color) { void surface_hline_f(SURFACE *surface, int x1, int x2, int y, int color) {
byte *p = surface_pointer(surface, x1, y); 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) { void surface_vline_f(SURFACE *surface, int x, int y1, int y2, int color) {
byte *p = surface_pointer(surface, x, y1); byte *p = surface_pointer(surface, x, y1);
int line_inc = surface->width; int line_inc = surface->width;
int y; int lines_left = y2 - y1 + 1;
for (y = y1; y <= y2; ++y, p += line_inc) { extern void draw_line(byte *dest, int color, int line_inc, int lines_left);
*p = (byte)color; #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) { 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) { void surface_rect(SURFACE *surface, int x1, int y1, int x2, int y2, int color) {
byte *p1, *p2; RECT clipped;
int width; int clipped_x2, clipped_y2;
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);
if (x1 < surface->clip_region.x) if (x2 < x1)
clipped_x1 = surface->clip_region.x; SWAP(int, x1, x2);
if (x2 > clip_right) if (y2 < y1)
clipped_x2 = clip_right; 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 // top line, only if y1 was within bounds
if (y1 < surface->clip_region.y) if (y1 == clipped.y) {
clipped_y1 = surface->clip_region.y; byte *p = surface_pointer(surface, clipped.x, clipped.y);
else mem_fill32(p, color, clipped.width);
memset(surface_pointer(surface, clipped_x1, clipped_y1), color, 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);
// 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;
} }
// bottom line, only if y2 was within bounds
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.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 // draw left line if x1 was not clipped
} else if (x1 == clipped_x1) { } else if (x1 == clipped.x) {
p1 = surface_pointer(surface, x1, y1); byte *p = surface_pointer(surface, clipped.x, clipped.y);
for (y = y1; y <= y2; ++y, p1 += y_inc) draw_vert_line(p, color, surface->width, clipped.height - 1);
*p1 = (byte)color;
// draw right line if x2 was not clipped // draw right line if x2 was not clipped
} else if (x2 == clipped_x2) { } else if (x2 == clipped_x2) {
p1 = surface_pointer(surface, x2, y1); byte *p = surface_pointer(surface, clipped_x2, clipped.y);
for (y = y1; y <= y2; ++y, p1 += y_inc) draw_vert_line(p, color, surface->width, clipped.height - 1);
*p1 = (byte)color;
} }
} }
void surface_rect_f(SURFACE *surface, int x1, int y1, int x2, int y2, int color) { 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 width = x2 - x1 + 1;
int y; int lines_left = y2 - y1;
int y_inc = surface->width; int y_inc = surface->width;
p1 = surface_pointer(surface, x1, y1); p = surface_pointer(surface, x1, y1);
p2 = surface_pointer(surface, x1, y2);
memset(p1, color, width);
memset(p2, color, width);
p1 = surface_pointer(surface, x1, y1); p1 = p;
p2 = surface_pointer(surface, x2, y1); p2 = p + width - 1;
for (y = y1; y <= y2; ++y, p1 += y_inc, p2 += y_inc) {
*p1 = (byte)color; direct_rect_f(color, width, y_inc, lines_left, p1, p2);
*p2 = (byte)color;
}
} }
void surface_filled_rect(SURFACE *surface, 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)) if (!clamp_to_region(&surface->clip_region, &x1, &y1, &x2, &y2))
return; 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); surface_filled_rect_f(surface, x1, y1, x2, y2, color);
} }
@ -245,14 +277,12 @@ void surface_filled_rect_f(SURFACE *surface,
int color) { int color) {
byte *p; byte *p;
int width = x2 - x1 + 1; int width = x2 - x1 + 1;
int y;
int y_inc = surface->width; int y_inc = surface->width;
int lines_left = y2 - y1 + 1;
p = surface_pointer(surface, x1, y1); p = surface_pointer(surface, x1, y1);
for (y = y1; y <= y2; ++y) {
memset(p, (byte)color, width); direct_filled_rect_f(color, y_inc, width, lines_left, p);
p += y_inc;
}
} }
#define CHAR_WIDTH 8 #define CHAR_WIDTH 8
@ -262,7 +292,7 @@ void surface_filled_rect_f(SURFACE *surface,
// dest_x, dest_y - original unclipped render x,y coords // dest_x, dest_y - original unclipped render x,y coords
// dest_clipped - clipped destination render region // dest_clipped - clipped destination render region
static inline void print_char(SURFACE *surface, static void print_char(SURFACE *surface,
int dest_x, int dest_x,
int dest_y, int dest_y,
const RECT *dest_clipped, const RECT *dest_clipped,
@ -277,7 +307,7 @@ static inline void print_char(SURFACE *surface,
int y_inc = surface->width; int y_inc = surface->width;
p = surface_pointer(surface, dest_clipped->x, dest_clipped->y); 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) // get offset x,y to start rendering char from (will be in range 0-7)
offset_x = dest_clipped->x - dest_x; offset_x = dest_clipped->x - dest_x;
@ -298,7 +328,7 @@ static inline void print_char(SURFACE *surface,
} }
} }
static inline void print_text(SURFACE *surface, static void print_text(SURFACE *surface,
int x, int x,
int y, int y,
int color, int color,
@ -311,12 +341,17 @@ static inline void print_text(SURFACE *surface,
r = rect(x, y, CHAR_WIDTH, CHAR_HEIGHT); r = rect(x, y, CHAR_WIDTH, CHAR_HEIGHT);
for (c = text; *c; ++c) { for (c = text; *c; ++c) {
if (*c == '\n') { switch (*c) {
case '\n':
r.x = x; r.x = x;
r.y += r.height; r.y += r.height;
} else if (*c == ' ') { break;
case ' ':
r.x += r.width; r.x += r.width;
} else { break;
case '\r':
break;
default:
if (clip) { if (clip) {
draw_r = r; draw_r = r;
if (clip_to_region(&surface->clip_region, &draw_r)) if (clip_to_region(&surface->clip_region, &draw_r))

View file

@ -1,18 +1,18 @@
#ifndef DGL_DRAW_H_INCLUDED #ifndef DGL_DGLDRAW_H_INCLUDED
#define DGL_DRAW_H_INCLUDED #define DGL_DGLDRAW_H_INCLUDED
#include "gfx.h" #include "dglgfx.h"
#include "clipping.h" #include "dglclip.h"
#include "util.h" #include "dglutil.h"
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);
static inline void surface_pset_f(SURFACE *surface, int x, int y, int color); static 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 int surface_point(const SURFACE *surface, int x, int y);
static inline int surface_point_f(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); 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_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(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); 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(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 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)) if (is_point_in_bounds(&surface->clip_region, x, y))
surface_pset_f(surface, x, y, color); surface_pset_f(surface, x, y, color);
} }
static inline void surface_pset_f(SURFACE *surface, int x, int y, int color) { static void surface_pset_f(SURFACE *surface, int x, int y, int color) {
*(surface_pointer(surface, x, y)) = (byte)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)) if (is_point_in_bounds(&surface->clip_region, x, y))
return surface_point_f(surface, x, y); return surface_point_f(surface, x, y);
else else
return 0; return 0;
} }
static inline int surface_point_f(const SURFACE *surface, int x, int y) { static int surface_point_f(const SURFACE *surface, int x, int y) {
return (int)*(surface_pointer(surface, x, 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) if (x2 < x1)
SWAP(int, x1, x2); SWAP(int, x1, x2);
if (clamp_to_region(&surface->clip_region, &x1, &y, &x2, &y)) if (clamp_to_region(&surface->clip_region, &x1, &y, &x2, &y))
surface_hline_f(surface, x1, x2, y, color); 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) if (y2 < y1)
SWAP(int, y1, y2); SWAP(int, y1, y2);
if (clamp_to_region(&surface->clip_region, &x, &y1, &x, &y2)) if (clamp_to_region(&surface->clip_region, &x, &y1, &x, &y2))

159
DGLDRAWA.ASM Normal file
View 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

View file

@ -1,7 +1,7 @@
#ifndef DGL_ERROR_H_INCLUDED #ifndef DGL_DGLERROR_H_INCLUDED
#define DGL_ERROR_H_INCLUDED #define DGL_DGLERROR_H_INCLUDED
#include "common.h" #include "dglcmn.h"
typedef enum { typedef enum {
DGL_NONE = 0, DGL_NONE = 0,

20
DGLFIXP.C Normal file
View 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
View 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
View 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
View 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

View file

@ -1,11 +1,8 @@
#include "keyboard.h" #include "dglkbrd.h"
#include "internal.h" #include "dglutil.h"
#include "util.h" #include "dglerror.h"
#include "error.h"
#include <string.h> #include <string.h>
#include <dpmi.h> #include <dos.h>
#include <pc.h>
#include <sys/nearptr.h>
#define PIC_CTRL_PORT 0x20 #define PIC_CTRL_PORT 0x20
#define KEYBRD_DATA_PORT 0x60 #define KEYBRD_DATA_PORT 0x60
@ -33,44 +30,43 @@ volatile KEY _key_scan;
uword _old_flags; uword _old_flags;
_go32_dpmi_seginfo _old_handler; void (interrupt far *_old_handler)();
_go32_dpmi_seginfo _new_handler;
static inline void reset_key_states() { static void reset_key_states() {
memset((void*)keys, 0, 128); memset((void*)keys, 0, 128);
} }
// waits until the keyboard status port indicates the data port // waits until the keyboard status port indicates the data port
// can be read from once again // can be read from once again
static inline void wait_kb_data_read() { static void wait_kb_data_read() {
while ((inportb(KEYBRD_STATUS_PORT) & BIT_0) == 0) { while ((inp(KEYBRD_STATUS_PORT) & BIT_0) == 0) {
} }
} }
// waits until the keyboard status port indicates the data port // waits until the keyboard status port indicates the data port
// can be written to once again // can be written to once again
static inline void wait_kb_data_write() { static void wait_kb_data_write() {
while ((inportb(KEYBRD_STATUS_PORT) & BIT_1) != 0) { while ((inp(KEYBRD_STATUS_PORT) & BIT_1) != 0) {
} }
} }
// sends data to the keyboard data port. checks for success // sends data to the keyboard data port. checks for success
// and returns TRUE if the data write succeeded // 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; ubyte result;
wait_kb_data_write(); wait_kb_data_write();
outportb(KEYBRD_DATA_PORT, data); outp(KEYBRD_DATA_PORT, data);
wait_kb_data_read(); wait_kb_data_read();
result = inportb(KEYBRD_DATA_PORT); result = inp(KEYBRD_DATA_PORT);
return (result == 0xFA); return (result == 0xFA);
} }
// keyboard interrupt handler // keyboard interrupt handler
void kb_int_handler(void) { void interrupt far kb_int_handler(void) {
// read scan code of key that was just pressed // 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) { if (_key_scan & 0x80) {
// high bit set indicates key was released, clear high bit to get // high bit set indicates key was released, clear high bit to get
// the actual key scan code // the actual key scan code
@ -83,19 +79,18 @@ void kb_int_handler(void) {
_key_last_scan = _key_scan; _key_last_scan = _key_scan;
// indicate key event was processed to keyboard controller // indicate key event was processed to keyboard controller
_key_scan = inportb(KEYBRD_CTRL_PORT) | 0x82; _key_scan = inp(KEYBRD_CTRL_PORT) | 0x82;
outportb(KEYBRD_CTRL_PORT, _key_scan); outp(KEYBRD_CTRL_PORT, _key_scan);
outportb(KEYBRD_CTRL_PORT, _key_scan & 0x7f); outp(KEYBRD_CTRL_PORT, _key_scan & 0x7f);
outportb(PIC_CTRL_PORT, 0x20); outp(PIC_CTRL_PORT, 0x20);
} }
END_OF_FUNCTION(kb_int_handler)
static uword get_kb_flags(void) { 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) { 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 // updates the keyboard indicator LEDs from the num/caps/scroll lock flags
@ -129,25 +124,18 @@ boolean keyboard_init(void) {
return FALSE; return FALSE;
} }
LOCK_MEMORY(keys, 128);
LOCK_VARIABLE(_key_scan);
LOCK_VARIABLE(_key_last_scan);
LOCK_FUNCTION(kb_int_handler);
// preserve old flags // preserve old flags
_old_flags = get_kb_flags(); _old_flags = get_kb_flags();
reset_key_states(); reset_key_states();
if (!_install_irq(9, kb_int_handler, &_new_handler, &_old_handler)) { _old_handler = _dos_getvect(9);
dgl_set_error(DGL_KEYBOARD_IRQ_INSTALL_FAILURE); _dos_setvect(9, kb_int_handler);
return FALSE;
}
// turn off keyboard LEDs since our interrupt handler does not currently // turn off keyboard LEDs since our interrupt handler does not currently
// respect the num/caps/scroll lock statuses // respect the num/caps/scroll lock statuses
_disable_interrupts(); int_disable();
update_kb_led(0); update_kb_led(0);
_enable_interrupts(); int_enable();
_installed = TRUE; _installed = TRUE;
return TRUE; return TRUE;
@ -158,14 +146,11 @@ boolean keyboard_shutdown(void) {
return TRUE; // don't care return TRUE; // don't care
// reset keyboard LEDs to previous state // reset keyboard LEDs to previous state
_disable_interrupts(); int_disable();
update_kb_led(_old_flags); update_kb_led(_old_flags);
_enable_interrupts(); int_enable();
if (!_restore_irq(9, &_new_handler, &_old_handler)) { _dos_setvect(9, _old_handler);
dgl_set_error(DGL_KEYBOARD_IRQ_RESTORE_FAILURE);
return FALSE;
}
reset_key_states(); reset_key_states();
// restore keyboard flags to previous state // restore keyboard flags to previous state

View file

@ -1,15 +1,15 @@
#ifndef DGL_KEYBOARD_H_INCLUDED #ifndef DGL_DGLKYBRD_H_INCLUDED
#define DGL_KEYBOARD_H_INCLUDED #define DGL_DGLKYBRD_H_INCLUDED
#include "common.h" #include "dglcmn.h"
#include "keys.h" #include "dglkeys.h"
typedef byte KEY; typedef byte KEY;
/* /*
* Current state of the keyboard. * Current state of the keyboard.
*/ */
volatile extern ubyte keys[128]; extern volatile ubyte keys[128];
/* /*
* Installs a custom keyboard interrupt handler. * Installs a custom keyboard interrupt handler.

View file

@ -1,5 +1,5 @@
#ifndef DGL_KEYS_H_INCLUDED #ifndef DGL_DGLKEYS_H_INCLUDED
#define DGL_KEYS_H_INCLUDED #define DGL_DGLKEYS_H_INCLUDED
#define KEY_ESC 0x01 #define KEY_ESC 0x01
#define KEY_1 0x02 #define KEY_1 0x02

View file

@ -1,4 +1,4 @@
#include "mathext.h" #include "dglmath.h"
#include <math.h> #include <math.h>
float angle_between_i(int x1, int y1, int x2, int y2) { float angle_between_i(int x1, int y1, int x2, int y2) {

View file

@ -1,12 +1,13 @@
#ifndef DGL_MATH_H_INCLUDED #ifndef DGL_DGLMATH_H_INCLUDED
#define DGL_MATH_H_INCLUDED #define DGL_DGLMATH_H_INCLUDED
#include "common.h" #include "dglcmn.h"
#include "vector2.h" #include "dglvec2.h"
#include <math.h> #include <math.h>
#define TOLERANCE 0.00001f #define TOLERANCE 0.00001f
#define PI 3.1415927f
#define PI_OVER_180 (PI / 180.0f) #define PI_OVER_180 (PI / 180.0f)
#define RADIANS_0 0.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); int next_power_of_2(int n);
void point_on_circle(float radius, float radians, float *x, float *y); void point_on_circle(float radius, float radians, float *x, float *y);
static inline VECTOR2F direction_from_angle(float radians); static VECTOR2F direction_from_angle(float radians);
static inline float round(float value); static float round(float value);
static inline float symmetrical_round(float value); static float symmetrical_round(float value);
static inline boolean close_enough(float a, float b, float tolerance); static boolean close_enough(float a, float b, float tolerance);
static inline boolean power_of_2(int n); static boolean power_of_2(int n);
static inline float smooth_step(float low, float high, float t); 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; VECTOR2F direction;
point_on_circle(1.0f, radians, &direction.x, &direction.y); point_on_circle(1.0f, radians, &direction.x, &direction.y);
return direction; return direction;
} }
static inline float round(float value) { static float round(float value) {
return ceil(value + 0.5f); return ceil(value + 0.5f);
} }
static inline float symmetrical_round(float value) { static float symmetrical_round(float value) {
if (value > 0.0f) if (value > 0.0f)
return floor(value + 0.5f); return floor(value + 0.5f);
else else
return ceil(value - 0.5f); 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; 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)); 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); float n = CLAMP(t, 0.0f, 1.0f);
return LERP(low, high, (n * n) * (3.0f - (2.0f * n))); return LERP(low, high, (n * n) * (3.0f - (2.0f * n)));
} }

159
DGLMOUSE.C Normal file
View 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(&regs, 0, sizeof(regs));
regs.w.ax = 0x00;
int386(0x33, &regs, &regs);
return (regs.w.ax != 0);
}
static void update_mouse_state(void) {
union REGS regs;
memset(&regs, 0, sizeof(regs));
regs.w.ax = 0x03;
int386(0x33, &regs, &regs);
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(&regs, 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, &regs, &regs, &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(&regs, 0, sizeof(regs));
regs.w.ax = 0x0c;
regs.w.cx = 0;
int386(0x33, &regs, &regs);
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(&regs, 0, sizeof(regs));
regs.w.ax = 0x01;
int386(0x33, &regs, &regs);
}
void mouse_hide(void) {
union REGS regs;
if (!_has_mouse)
return;
memset(&regs, 0, sizeof(regs));
regs.w.ax = 0x02;
int386(0x33, &regs, &regs);
}
void mouse_set_bounds(int min_x, int min_y, int max_x, int max_y) {
union REGS regs;
if (!_has_mouse)
return;
memset(&regs, 0, sizeof(regs));
regs.w.ax = 0x07;
regs.w.cx = min_x;
regs.w.dx = max_x;
int386(0x33, &regs, &regs);
regs.w.ax = 0x08;
regs.w.cx = min_y;
regs.w.dx = max_y;
int386(0x33, &regs, &regs);
}

View file

@ -1,7 +1,7 @@
#ifndef DGL_MOUSE_H_INCLUDED #ifndef DGL_DGLMOUSE_H_INCLUDED
#define DGL_MOUSE_H_INCLUDED #define DGL_DGLMOUSE_H_INCLUDED
#include "common.h" #include "dglcmn.h"
#define MOUSE_LEFTBUTTON 0x01 #define MOUSE_LEFTBUTTON 0x01
#define MOUSE_RIGHTBUTTON 0x02 #define MOUSE_RIGHTBUTTON 0x02
@ -10,27 +10,27 @@
/* /*
* Current mouse cursor X position. * Current mouse cursor X position.
*/ */
volatile extern int mouse_x; extern volatile int mouse_x;
/* /*
* Current mouse cursor Y position. * Current mouse cursor Y position.
*/ */
volatile extern int mouse_y; extern volatile int mouse_y;
/* /*
* Current state of mouse buttons. * 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. * 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. * 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. * 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. * @param button The button to check the status of.
* @return TRUE if the button is pressed. * @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; return (mouse_buttons & button) != 0;
} }

View file

@ -1,9 +1,9 @@
#ifndef DGL_MATRIX33_H_INCLUDED #ifndef DGL_DGLMAT33_H_INCLUDED
#define DGL_MATRIX33_H_INCLUDED #define DGL_DGLMAT33_H_INCLUDED
#include "common.h" #include "dglcmn.h"
#include "mathext.h" #include "dglmath.h"
#include "vector2.h" #include "dglvec2.h"
#include <math.h> #include <math.h>
#define _M33_11 0 #define _M33_11 0
@ -20,33 +20,33 @@ typedef struct {
float m[9]; float m[9];
} MATRIX33; } MATRIX33;
static inline MATRIX33 matrix33(float m11, float m12, float m13, static MATRIX33 matrix33(float m11, float m12, float m13,
float m21, float m22, float m23, float m21, float m22, float m23,
float m31, float m32, float m33); float m31, float m32, float m33);
static inline void matrix33_set(MATRIX33 *m, static void matrix33_set(MATRIX33 *m,
float m11, float m12, float m13, float m11, float m12, float m13,
float m21, float m22, float m23, float m21, float m22, float m23,
float m31, float m32, float m33); float m31, float m32, float 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);
static inline MATRIX33 matrix33_rotation_x(float radians); static MATRIX33 matrix33_rotation_x(float radians);
static inline MATRIX33 matrix33_rotation_y(float radians); static MATRIX33 matrix33_rotation_y(float radians);
static inline MATRIX33 matrix33_rotation_z(float radians); static MATRIX33 matrix33_rotation_z(float radians);
static inline MATRIX33 matrix33_add(MATRIX33 a, MATRIX33 b); static MATRIX33 matrix33_add(MATRIX33 a, MATRIX33 b);
static inline MATRIX33 matrix33_sub(MATRIX33 a, MATRIX33 b); static MATRIX33 matrix33_sub(MATRIX33 a, MATRIX33 b);
static inline MATRIX33 matrix33_mul(MATRIX33 a, MATRIX33 b); static MATRIX33 matrix33_mul(MATRIX33 a, MATRIX33 b);
static inline MATRIX33 matrix33_scale(MATRIX33 m, float scale); static MATRIX33 matrix33_scale(MATRIX33 m, float scale);
static inline float matrix33_determinant(MATRIX33 m); static float matrix33_determinant(MATRIX33 m);
static inline MATRIX33 matrix33_inverse(MATRIX33 m); static MATRIX33 matrix33_inverse(MATRIX33 m);
static inline MATRIX33 matrix33_transpose(MATRIX33 m); static MATRIX33 matrix33_transpose(MATRIX33 m);
static inline VECTOR2F matrix33_transform(MATRIX33 m, VECTOR2F v); static VECTOR2F matrix33_transform(MATRIX33 m, VECTOR2F v);
static inline MATRIX33 matrix33_translation_2d(float x, float y); static MATRIX33 matrix33_translation_2d(float x, float y);
static inline MATRIX33 matrix33_scaling_2d(float x, float y); static MATRIX33 matrix33_scaling_2d(float x, float y);
static inline MATRIX33 matrix33_rotation_2d(float radians); static MATRIX33 matrix33_rotation_2d(float radians);
static inline VECTOR2F matrix33_transform_2d(MATRIX33 m, VECTOR2F v); static VECTOR2F matrix33_transform_2d(MATRIX33 m, VECTOR2F v);
#define IDENTITY_MATRIX33 matrix33(1.0f, 0.0f, 0.0f, \ #define IDENTITY_MATRIX33 matrix33(1.0f, 0.0f, 0.0f, \
0.0f, 1.0f, 0.0f, \ 0.0f, 1.0f, 0.0f, \
@ -54,7 +54,7 @@ static inline VECTOR2F matrix33_transform_2d(MATRIX33 m, VECTOR2F v);
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
static inline MATRIX33 matrix33(float m11, float m12, float m13, static MATRIX33 matrix33(float m11, float m12, float m13,
float m21, float m22, float m23, float m21, float m22, float m23,
float m31, float m32, float m33) { float m31, float m32, float m33) {
MATRIX33 result; MATRIX33 result;
@ -70,7 +70,7 @@ static inline MATRIX33 matrix33(float m11, float m12, float m13,
return result; return result;
} }
static inline void matrix33_set(MATRIX33 *m, static void matrix33_set(MATRIX33 *m,
float m11, float m12, float m13, float m11, float m12, float m13,
float m21, float m22, float m23, float m21, float m22, float m23,
float m31, float m32, float m33) { float m31, float m32, float m33) {
@ -85,7 +85,7 @@ static inline void matrix33_set(MATRIX33 *m,
m->m[_M33_33] = m33; 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; MATRIX33 rx, ry, rz;
rx = matrix33_rotation_x(x); rx = matrix33_rotation_x(x);
ry = matrix33_rotation_y(y); 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); 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; MATRIX33 result;
float s, c; float s, c;
@ -115,7 +115,7 @@ static inline MATRIX33 matrix33_rotation_x(float radians) {
return result; return result;
} }
static inline MATRIX33 matrix33_rotation_y(float radians) { static MATRIX33 matrix33_rotation_y(float radians) {
MATRIX33 result; MATRIX33 result;
float s, c; float s, c;
@ -137,7 +137,7 @@ static inline MATRIX33 matrix33_rotation_y(float radians) {
return result; return result;
} }
static inline MATRIX33 matrix33_rotation_z(float radians) { static MATRIX33 matrix33_rotation_z(float radians) {
MATRIX33 result; MATRIX33 result;
float s, c; float s, c;
@ -159,7 +159,7 @@ static inline MATRIX33 matrix33_rotation_z(float radians) {
return result; return result;
} }
static inline MATRIX33 matrix33_add(MATRIX33 a, MATRIX33 b) { static MATRIX33 matrix33_add(MATRIX33 a, MATRIX33 b) {
MATRIX33 result; MATRIX33 result;
result.m[_M33_11] = a.m[_M33_11] + b.m[_M33_11]; 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; return result;
} }
static inline MATRIX33 matrix33_sub(MATRIX33 a, MATRIX33 b) { static MATRIX33 matrix33_sub(MATRIX33 a, MATRIX33 b) {
MATRIX33 result; MATRIX33 result;
result.m[_M33_11] = a.m[_M33_11] - b.m[_M33_11]; 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; return result;
} }
static inline MATRIX33 matrix33_mul(MATRIX33 a, MATRIX33 b) { static MATRIX33 matrix33_mul(MATRIX33 a, MATRIX33 b) {
MATRIX33 result; 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]; 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; return result;
} }
static inline MATRIX33 matrix33_scale(MATRIX33 m, float scale) { static MATRIX33 matrix33_scale(MATRIX33 m, float scale) {
MATRIX33 result; MATRIX33 result;
result.m[_M33_11] = m.m[_M33_11] * scale; result.m[_M33_11] = m.m[_M33_11] * scale;
@ -225,7 +225,7 @@ static inline MATRIX33 matrix33_scale(MATRIX33 m, float scale) {
return result; return result;
} }
static inline float matrix33_determinant(MATRIX33 m) { static float matrix33_determinant(MATRIX33 m) {
return return
m.m[_M33_11] * m.m[_M33_22] * m.m[_M33_33] + m.m[_M33_11] * m.m[_M33_22] * m.m[_M33_33] +
m.m[_M33_12] * m.m[_M33_23] * m.m[_M33_31] + 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]; 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; float d;
MATRIX33 result; MATRIX33 result;
d = matrix33_determinant(m); 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; MATRIX33 result;
result.m[_M33_11] = m.m[_M33_11]; result.m[_M33_11] = m.m[_M33_11];
@ -276,7 +276,7 @@ static inline MATRIX33 matrix33_transpose(MATRIX33 m) {
return result; return result;
} }
static inline VECTOR2F matrix33_transform(MATRIX33 m, VECTOR2F v) { static VECTOR2F matrix33_transform(MATRIX33 m, VECTOR2F v) {
VECTOR2F result; VECTOR2F result;
result.x = v.x * m.m[_M33_11] + v.y * m.m[_M33_12] + m.m[_M33_13]; 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; return result;
} }
static inline MATRIX33 matrix33_translation_2d(float x, float y) { static MATRIX33 matrix33_translation_2d(float x, float y) {
MATRIX33 result; MATRIX33 result;
result.m[_M33_11] = 1.0f; result.m[_M33_11] = 1.0f;
@ -303,7 +303,7 @@ static inline MATRIX33 matrix33_translation_2d(float x, float y) {
return result; return result;
} }
static inline MATRIX33 matrix33_scaling_2d(float x, float y) { static MATRIX33 matrix33_scaling_2d(float x, float y) {
MATRIX33 result; MATRIX33 result;
result.m[_M33_11] = x; result.m[_M33_11] = x;
@ -321,11 +321,11 @@ static inline MATRIX33 matrix33_scaling_2d(float x, float y) {
return result; return result;
} }
static inline MATRIX33 matrix33_rotation_2d(float radians) { static MATRIX33 matrix33_rotation_2d(float radians) {
return matrix33_rotation_z(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; VECTOR2F result;
result.x = v.x * m.m[_M33_11] + v.y * m.m[_M33_12] + m.m[_M33_13]; result.x = v.x * m.m[_M33_11] + v.y * m.m[_M33_12] + m.m[_M33_13];

109
DGLPAL.C Normal file
View 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
View 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

View file

@ -1,8 +1,10 @@
#include "pcx.h" #include "dglpcx.h"
#include "gfx.h" #include "dglgfx.h"
#include "draw.h" #include "dglpal.h"
#include "error.h" #include "dgldraw.h"
#include "dglerror.h"
#include <stdio.h> #include <stdio.h>
#include <string.h>
typedef struct { typedef struct {
byte manufacturer; byte manufacturer;
@ -28,7 +30,7 @@ typedef struct {
SURFACE* pcx_load(const char *filename, byte *pcx_palette) { SURFACE* pcx_load(const char *filename, byte *pcx_palette) {
FILE *fp; FILE *fp;
PCX_HEADER header; PCX_HEADER header;
int i, n, count; int i, n, count, x, y;
SURFACE *pcx; SURFACE *pcx;
ubyte data; ubyte data;
@ -56,25 +58,30 @@ SURFACE* pcx_load(const char *filename, byte *pcx_palette) {
pcx = surface_create(header.width + 1, header.height + 1); pcx = surface_create(header.width + 1, header.height + 1);
// read pixel data
i = 0; i = 0;
while (i < (header.width * header.height)) { for (y = 0; y < (header.height + 1); ++y) {
n = fread(&data, 1, 1, fp); // write pixels out per-scanline (technically this is what the pcx
if (n == -1) // standard specifies, though a lot of pcx loaders don't do this).
goto pcx_load_error; x = 0;
while (x < header.bytes_per_line) {
if (data >= 192) { // read pixel (or RLE count...)
count = data - 192; data = fgetc(fp);
n = fread(&data, 1, 1, fp); if ((data & 0xc0) == 0xc0) {
if (n == -1) // was an RLE count, pixel is next byte
goto pcx_load_error; count = data & 0x3f;
data = fgetc(fp);
while (count > 0) {
pcx->pixels[i++] = data;
count--;
}
} else { } else {
pcx->pixels[i++] = data; count = 1;
}
// store this pixel colour the specified number of times
while (count--) {
if (x < pcx->width) {
pcx->pixels[i] = data;
}
++i;
++x;
}
} }
} }
@ -100,7 +107,7 @@ pcx_load_error:
return NULL; 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; int n;
if ((run_count > 1) || ((pixel & 0xc0) == 0xc0)) { if ((run_count > 1) || ((pixel & 0xc0) == 0xc0)) {
@ -198,7 +205,7 @@ boolean pcx_save(const char *filename, const SURFACE *src, const byte *palette)
} }
} else { } else {
for (i = 0; i < 256; ++i) { 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); n = fputc(r << 2, fp);
if (n == -1) if (n == -1)

View file

@ -1,8 +1,8 @@
#ifndef DGL_PCX_H_INCLUDED #ifndef DGL_DGLPCX_H_INCLUDED
#define DGL_PCX_H_INCLUDED #define DGL_DGLPCX_H_INCLUDED
#include "common.h" #include "dglcmn.h"
#include "gfx.h" #include "dglgfx.h"
SURFACE* pcx_load(const char *filename, byte *pcx_palette); SURFACE* pcx_load(const char *filename, byte *pcx_palette);
boolean pcx_save(const char *filename, const SURFACE *src, const byte *palette); boolean pcx_save(const char *filename, const SURFACE *src, const byte *palette);

View file

@ -1,5 +1,5 @@
#ifndef DGL_RECT_H_INCLUDED #ifndef DGL_DGLRECT_H_INCLUDED
#define DGL_RECT_H_INCLUDED #define DGL_DGLRECT_H_INCLUDED
typedef struct { typedef struct {
int x; int x;
@ -8,13 +8,13 @@ typedef struct {
int height; int height;
} RECT; } RECT;
static inline RECT rect(int x, int y, int width, int height); static RECT rect(int x, int y, int width, int height);
static inline int rect_right(const RECT *r); static int rect_right(const RECT *r);
static inline int rect_bottom(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; RECT result;
result.x = x; result.x = x;
result.y = y; result.y = y;
@ -23,14 +23,14 @@ static inline RECT rect(int x, int y, int width, int height) {
return result; return result;
} }
static inline int rect_right(const RECT *r) { static int rect_right(const RECT *r) {
if (r->width) if (r->width)
return r->x + r->width - 1; return r->x + r->width - 1;
else else
return r->x; return r->x;
} }
static inline int rect_bottom(const RECT *r) { static int rect_bottom(const RECT *r) {
if (r->height) if (r->height)
return r->y + r->height - 1; return r->y + r->height - 1;
else else

22
DGLUTIL.C Normal file
View 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
View 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
View 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
View file

@ -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(&regs, 0, sizeof(__dpmi_regs));
regs.h.ah = 0x00;
regs.h.al = 0x13;
if (__dpmi_int(0x10, &regs)) {
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(&regs, 0, sizeof(__dpmi_regs));
regs.h.ah = 0x00;
regs.h.al = 0x03;
if (__dpmi_int(0x10, &regs)) {
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
View file

@ -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

View file

@ -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;
}

View file

@ -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

Binary file not shown.

Binary file not shown.

80
MAKEFILE Normal file
View 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
View file

@ -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(&regs, 0, sizeof(__dpmi_regs));
regs.x.ax = 0x00;
__dpmi_int(0x33, &regs);
return (regs.x.ax != 0);
}
static void update_mouse_state(void) {
__dpmi_regs regs;
memset(&regs, 0, sizeof(__dpmi_regs));
regs.x.ax = 0x03;
__dpmi_int(0x33, &regs);
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(&regs, 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, &regs) != 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(&regs, 0, sizeof(__dpmi_regs));
regs.x.ax = 0x0c;
regs.x.cx = 0;
regs.x.dx = 0;
regs.x.es = 0;
if (__dpmi_int(0x33, &regs) != 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(&regs, 0, sizeof(__dpmi_regs));
regs.x.ax = 0x01;
__dpmi_int(0x33, &regs);
}
void mouse_hide(void) {
__dpmi_regs regs;
if (!_has_mouse)
return;
memset(&regs, 0, sizeof(__dpmi_regs));
regs.x.ax = 0x02;
__dpmi_int(0x33, &regs);
}
void mouse_set_bounds(int min_x, int min_y, int max_x, int max_y) {
__dpmi_regs regs;
if (!_has_mouse)
return;
memset(&regs, 0, sizeof(__dpmi_regs));
regs.x.ax = 0x07;
regs.x.cx = min_x;
regs.x.dx = max_x;
__dpmi_int(0x33, &regs);
regs.x.ax = 0x08;
regs.x.cx = min_y;
regs.x.dx = max_y;
__dpmi_int(0x33, &regs);
}

1200
TEST.C

File diff suppressed because it is too large Load diff

37
UTIL.C
View file

@ -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
View file

@ -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
View file

@ -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