From 84920e46d64c94304670d54a6ffa7ea490ff2ded Mon Sep 17 00:00:00 2001 From: gered Date: Mon, 30 Apr 2018 18:23:39 -0400 Subject: [PATCH] organize test code a bit better --- MAKEFILE | 22 - README.md | 10 +- TEST.C | 1197 ------------------------------------- TEST/BLIT.C | 210 +++++++ TEST/BLIT.H | 10 + TEST/FIXED.C | 69 +++ TEST/FIXED.H | 7 + TEST/HELPERS.H | 24 + TEST/LINE.C | 208 +++++++ TEST/LINE.H | 12 + TEST/MAKEFILE | 57 ++ TEST/PAL.C | 64 ++ TEST/PAL.H | 8 + TEST/PCX.C | 37 ++ TEST/PCX.H | 7 + TEST/PSET.C | 114 ++++ TEST/PSET.H | 9 + TEST/RECT.C | 208 +++++++ TEST/RECT.H | 10 + TEST/SURFACE.C | 21 + TEST/SURFACE.H | 8 + TEST/TEST.C | 75 +++ TEST.PCX => TEST/TEST.PCX | Bin TEST/TEXT.C | 95 +++ TEST/TEXT.H | 8 + TEST/VECTOR2.C | 134 +++++ TEST/VECTOR2.H | 8 + 27 files changed, 1409 insertions(+), 1223 deletions(-) delete mode 100644 TEST.C create mode 100644 TEST/BLIT.C create mode 100644 TEST/BLIT.H create mode 100644 TEST/FIXED.C create mode 100644 TEST/FIXED.H create mode 100644 TEST/HELPERS.H create mode 100644 TEST/LINE.C create mode 100644 TEST/LINE.H create mode 100644 TEST/MAKEFILE create mode 100644 TEST/PAL.C create mode 100644 TEST/PAL.H create mode 100644 TEST/PCX.C create mode 100644 TEST/PCX.H create mode 100644 TEST/PSET.C create mode 100644 TEST/PSET.H create mode 100644 TEST/RECT.C create mode 100644 TEST/RECT.H create mode 100644 TEST/SURFACE.C create mode 100644 TEST/SURFACE.H create mode 100644 TEST/TEST.C rename TEST.PCX => TEST/TEST.PCX (100%) create mode 100644 TEST/TEXT.C create mode 100644 TEST/TEXT.H create mode 100644 TEST/VECTOR2.C create mode 100644 TEST/VECTOR2.H diff --git a/MAKEFILE b/MAKEFILE index 50599dd..1fbc1b2 100644 --- a/MAKEFILE +++ b/MAKEFILE @@ -18,8 +18,6 @@ object_files = & 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)) @@ -38,17 +36,6 @@ asm_flags = /m /ml $(asm_flags_$(target_config)) .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 @@ -65,16 +52,7 @@ clean : .SYMBOLIC .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 - diff --git a/README.md b/README.md index 0e5a071..2c58612 100644 --- a/README.md +++ b/README.md @@ -61,11 +61,13 @@ To build the library: Will output `DGL.LIB` in the project directory. -To build and run a test program from `TEST.C` using the libDGL sources statically linked: +To build and run the (incomplete) test suite, look under the "TEST" directory. There you will +find a separate `MAKEFILE` which assumes that you are running `wmake` from that directory and +that `DGL.LIB` has already been built. ``` -> wmake run - -> wmake debug ; run through WD debugger +> cd test +test> wmake run ; run test suite +test> wmake debug ; run through WD debugger ``` diff --git a/TEST.C b/TEST.C deleted file mode 100644 index eb2f76d..0000000 --- a/TEST.C +++ /dev/null @@ -1,1197 +0,0 @@ -#include -#include -#include -#include -#include -#include "dgl.h" - -SURFACE *backbuffer = NULL; - -#define F_EQU(a, b) (close_enough((a), (b), TOLERANCE)) -#define FFIX_EQU(a, b) (close_enough((a), (b), 0.01f)) - -extern void _breakpoint(); -#pragma aux _breakpoint = "int 0x03"; - - -#define ASSERT(x) \ - do { \ - if (!(x)) { \ - printf("Assertion failed at %s:%d, %s\n", __FILE__, __LINE__, #x); \ - _breakpoint(); \ - } \ - } while (0) - -void break_handler(int sig) { - exit(0); -} - -SURFACE* get_sprite(int width, int height) { - int x_third, y_third; - SURFACE *sprite = surface_create(width, height); - ASSERT(sprite != NULL); - ASSERT(sprite->width == width); - ASSERT(sprite->height == height); - - x_third = width / 3; - y_third = height / 3; - - surface_filled_rect(sprite, 0, 0, x_third, y_third, 1); - surface_filled_rect(sprite, x_third * 2, y_third * 2, width - 1, height - 1, 2); - surface_filled_rect(sprite, 0, (y_third * 2), x_third, height - 1, 3); - surface_filled_rect(sprite, x_third * 2, 0, width - 1, y_third, 4); - surface_filled_rect(sprite, x_third, y_third, x_third * 2, y_third * 2, 5); - surface_rect(sprite, 0, 0, width - 1, height - 1, 6); - - return sprite; -} - -SURFACE* get_image(int width, int height) { - int x, y; - SURFACE *image = surface_create(width, height); - ASSERT(image != NULL); - ASSERT(image->width == width); - ASSERT(image->height == height); - - surface_filled_rect(image, 0, 0, width / 2, height / 2, 1); - surface_filled_rect(image, width / 2, 0, width - 1, height / 2, 2); - surface_filled_rect(image, 0, height / 2, width / 2, height - 1, 3); - surface_filled_rect(image, width / 2, height / 2, width - 1, height - 1, 4); - surface_rect(image, 0, 0, width - 1, height - 1, 5); - - return image; -} - -// --------------------------------------------------------------------------- - -void test_fixed(void) { - fixed a, b, c; - float af, bf, cf, f; - int i; - - a = FTOFIX(PI); - f = FIXTOF(a); - ASSERT(FFIX_EQU(PI, f)); - - a = FTOFIX(-0.37f); - f = FIXTOF(a); - ASSERT(FFIX_EQU(-0.38f, f)); - - a = ITOFIX(17); - i = FIXTOI(a); - ASSERT(17 == i); - - a = ITOFIX(-17); - i = FIXTOI(a); - ASSERT(-17 == i); - - a = FTOFIX(1.5f); - b = FTOFIX(2.3f); - c = a + b; - f = FIXTOF(c); - ASSERT(FFIX_EQU((1.5f + 2.3f), f)); - - a = FTOFIX(0.2f); - b = FTOFIX(1.7f); - c = a - b; - f = FIXTOF(c); - ASSERT(FFIX_EQU((0.2f - 1.7f), f)); - - a = FTOFIX(16.0f); - c = a >> 2; - f = FIXTOF(c); - ASSERT(FFIX_EQU((16 >> 2), f)); - - a = FTOFIX(7.1f); - b = ITOFIX(2); - c = fix_mul(a, b); - f = FIXTOF(c); - ASSERT(FFIX_EQU((7.1f * 2), f)); - - a = FTOFIX(77.7f); - b = ITOFIX(3); - c = fix_div(a, b); - f = FIXTOF(c); - ASSERT(FFIX_EQU((77.7f / 3), f)); - - for (i = 0; i <= 360; i += 45) { - f = DEG_TO_RAD(i + 1); - a = fix_sin(FTOFIX(f)); - af = sin(f); - b = fix_cos(FTOFIX(f)); - bf = cos(f); - c = fix_tan(FTOFIX(f)); - cf = tan(f); - ASSERT(FFIX_EQU(FIXTOF(a), af)); - ASSERT(FFIX_EQU(FIXTOF(b), bf)); - ASSERT(FFIX_EQU(FIXTOF(c), cf)); - } -} - -void test_vector2i(void) { - VECTOR2I a, b, c; - int i; - - c = vector2i(3, 7); - ASSERT(c.x == 3 && c.y == 7); - - vector2i_set(&c, 1, 2); - ASSERT(c.x == 1 && c.y == 2); - - a = vector2i(1, 2); - b = vector2i(1, 2); - ASSERT(vector2i_equals(a, b)); - - a = vector2i(3, 4); - b = vector2i(1, 2); - - c = vector2i_add(a, b); - ASSERT(c.x == 4 && c.y == 6); - - c = vector2i_sub(a, b); - ASSERT(c.x == 2 && c.y == 2); - - c = vector2i_mul(a, b); - ASSERT(c.x == 3 && c.y == 8); - - c = vector2i_muls(a, 2); - ASSERT(c.x == 6 && c.y == 8); - - c = vector2i_div(a, b); - ASSERT(c.x == 3 && c.y == 2); - - c = vector2i_divs(a, 2); - ASSERT(c.x == 1 && c.y == 2); - - a = vector2i(1, 1); - b = vector2i(1, 3); - i = vector2i_distance(a, b); - ASSERT(i == 2); - - i = vector2i_distancesq(a, b); - ASSERT(i == 4); - - a = vector2i(-12, 16); - b = vector2i(12, 9); - i = vector2i_dot(a, b); - ASSERT(i == 0); - - a = vector2i(-3, 0); - i = vector2i_length(a); - ASSERT(i == 3); - - i = vector2i_lengthsq(a); - ASSERT(i == 9); - - a = vector2i(5, 0); - b = vector2i(10, 0); - c = vector2i_lerp(a, b, 0.5f); - ASSERT(c.x == 7 && c.y == 0); -} - -void test_vector2f(void) { - VECTOR2F a, b, c; - float f; - - c = vector2f(3.0f, 7.0f); - ASSERT(F_EQU(c.x, 3.0f) && F_EQU(c.y, 7.0f)); - - vector2f_set(&c, 1.0f, 2.0f); - ASSERT(F_EQU(c.x, 1.0f) && F_EQU(c.y, 2.0f)); - - a = vector2f(1.0f, 2.0f); - b = vector2f(1.0f, 2.0f); - ASSERT(vector2f_equals(a, b)); - - a = vector2f(3.0f, 4.0f); - b = vector2f(1.0f, 2.0f); - - c = vector2f_add(a, b); - ASSERT(F_EQU(c.x, 4.0f) && F_EQU(c.y, 6.0f)); - - c = vector2f_sub(a, b); - ASSERT(F_EQU(c.x, 2.0f) && F_EQU(c.y, 2.0f)); - - c = vector2f_mul(a, b); - ASSERT(F_EQU(c.x, 3.0f) && F_EQU(c.y, 8.0f)); - - c = vector2f_muls(a, 0.5f); - ASSERT(F_EQU(c.x, 1.5f) && F_EQU(c.y, 2.0f)); - - c = vector2f_div(a, b); - ASSERT(F_EQU(c.x, 3.0f) && F_EQU(c.y, 2.0f)); - - c = vector2f_divs(a, 0.5f); - ASSERT(F_EQU(c.x, 6.0f) && F_EQU(c.y, 8.0f)); - - a = vector2f(1.0f, 1.0f); - b = vector2f(1.0f, 3.0f); - f = vector2f_distance(a, b); - ASSERT(F_EQU(f, 2.0f)); - - f = vector2f_distancesq(a, b); - ASSERT(F_EQU(f, 4.0f)); - - a = vector2f(-12.0f, 16.0f); - b = vector2f(12.0f, 9.0f); - f = vector2f_dot(a, b); - ASSERT(F_EQU(f, 0.0f)); - - a = vector2f(-3.0f, 0.0f); - f = vector2f_length(a); - ASSERT(F_EQU(f, 3.0f)); - - f = vector2f_lengthsq(a); - ASSERT(F_EQU(f, 9.0f)); - - a = vector2f(7.0f, 7.0f); - c = vector2f_normalize(a); - ASSERT(F_EQU(c.x, 0.70710f) && F_EQU(c.y, 0.70710f)); - - a = vector2f(10.0f, 0.0f); - c = vector2f_set_length(a, 2.0f); - ASSERT(F_EQU(c.x, 2.0f) && F_EQU(c.y, 0.0f)); - - a = vector2f(5.0f, 0.0f); - b = vector2f(10.0f, 0.0f); - c = vector2f_lerp(a, b, 0.5f); - ASSERT(F_EQU(c.x, 7.5f) && F_EQU(c.y, 0.0f)); -} - -// fill screen entirely with blue -void test_surface_clear(void) { - surface_clear(screen, 1); - - getch(); -} - -// fill screen entirely with green, using the backbuffer first -void test_surface_copy(void) { - surface_clear(backbuffer, 2); - surface_copy(backbuffer, screen); - - getch(); -} - -// pixel drawing done largely using pointers directly, with the assistance -// of helper functions to get correct initial pointer positions. -// starting at (10,10), draw 256 colour palette in a 16x16 pixel box. -// draw white "guide" lines from (0,0) to (10,10) -void test_pixels_1(void) { - byte *p; - int i, x, y; - - surface_clear(screen, 0); - - p = surface_pointer(screen, 10, 10); - ASSERT(p == (screen->pixels + (10 * screen->width) + 10)); - - i = 0; - for (y = 0; y < 16; ++y) { - for (x = 0; x < 16; ++x) { - *p = (byte)i; - ++p; - ++i; - } - p += (screen->width - 16); - } - - p = surface_pointer(screen, 0, 0); - for (i = 0; i < 10; ++i) { - *p = 15; - p += (screen->width + 1); - } - p = surface_pointer(screen, 10, 0); - for (i = 0; i < 10; ++i) { - *p = 15; - p += screen->width; - } - p = surface_pointer(screen, 0, 10); - for (i = 0; i < 10; ++i) { - *p = 15; - ++p; - } - - getch(); -} - -// pixel drawing using pset, and pixel getting using point -// draws two blue, green, cyan, red pixels each in each screen corner. -// the second pixel colour is drawn by sampling the first. -void test_pixels_2(void) { - byte c1, c2, c3, c4; - - surface_clear(screen, 0); - - surface_pset(screen, 0, 0, 1); - surface_pset(screen, 319, 0, 2); - surface_pset(screen, 0, 199, 3); - surface_pset(screen, 319, 199, 4); - - surface_pset_f(screen, 10, 0, 1); - surface_pset_f(screen, 309, 0, 2); - surface_pset_f(screen, 10, 199, 3); - surface_pset_f(screen, 309, 199, 4); - - c1 = surface_point(screen, 0, 0); - c2 = surface_point(screen, 319, 0); - c3 = surface_point(screen, 0, 199); - c4 = surface_point(screen, 319, 199); - ASSERT(c1 == 1 && c2 == 2 && c3 == 3 && c4 == 4); - - surface_pset(screen, 1, 1, c1); - surface_pset(screen, 318, 1, c2); - surface_pset(screen, 1, 198, c3); - surface_pset(screen, 318, 198, c4); - - c1 = surface_point_f(screen, 10, 0); - c2 = surface_point_f(screen, 309, 0); - c3 = surface_point_f(screen, 10, 199); - c4 = surface_point_f(screen, 309, 199); - ASSERT(c1 == 1 && c2 == 2 && c3 == 3 && c4 == 4); - - surface_pset_f(screen, 11, 1, c1); - surface_pset_f(screen, 308, 1, c2); - surface_pset_f(screen, 11, 198, c3); - surface_pset_f(screen, 308, 198, c4); - - getch(); -} - -// pixel drawing with clipping (using pset). -// draws 4 white lines 10 pixels long, going 5 pixels out of bounds off each -// edge (top, left, bottom, right) of the screen. red marker pixels are at -// the inside edge of each line to mark a known reference point -void test_pixels_clipping(void) { - int i, x, y; - - surface_clear(screen, 0); - - surface_pset(screen, 5, 100, 4); - surface_pset(screen, 314, 100, 4); - surface_pset(screen, 160, 5, 4); - surface_pset(screen, 160, 194, 4); - - for (i = 0; i < 10; ++i) { - surface_pset(screen, i - 5, 100, 15); - surface_pset(screen, 315 + i, 100, 15); - surface_pset(screen, 160, i - 5, 15); - surface_pset(screen, 160, 195 + i, 15); - } - - getch(); -} - -// draws two horizontal lines, with red pixels marking the extents of the -// lines. a third line is drawn using the "fast" variant. -void test_hline(void) { - int x1, x2, y; - - surface_clear(screen, 0); - - x1 = 10; x2 = 100; y = 20; - - surface_pset(screen, x1 - 1, y, 4); - surface_pset(screen, x2 + 1, y, 4); - surface_hline(screen, x1, x2, y, 1); - - y = 30; - - surface_pset(screen, x1 - 1, y, 4); - surface_pset(screen, x2 + 1, y, 4); - surface_hline(screen, x2, x1, y, 2); - - x1 = 200; x2 = 300; y = 20; - - surface_pset(screen, x1 - 1, y, 4); - surface_pset(screen, x2 + 1, y, 4); - surface_hline_f(screen, x1, x2, y, 1); - - getch(); -} - -// draws 4 horizontal lines. two are completely outside the bounds of -// the screen and should not be visible at all. the remaining two will be -// partly out of bounds off the left and right edges. red pixel markers are -// drawn marking the visible ends of the two partly clipped lines -void test_hline_clipping(void) { - int x1, x2, y; - - surface_clear(screen, 0); - - x1 = -50; x2 = 50; y = 6; - surface_pset(screen, x2 + 1, y, 4); - surface_hline(screen, x1, x2, y, 1); - - x1 = 300; x2 = 340; y = 130; - surface_pset(screen, x1 - 1, y, 4); - surface_hline(screen, x1, x2, y, 2); - - surface_hline(screen, 100, 200, -10, 3); - surface_hline(screen, 20, 80, 250, 5); - - getch(); -} - -// draws two vertical lines, with red pixels marking the extents of -// the lines. a third line is drawn using the "fast" variant. -void test_vline(void) { - int x, y1, y2; - - surface_clear(screen, 0); - - x = 50; y1 = 10; y2 = 100; - - surface_pset(screen, x, y1 - 1, 4); - surface_pset(screen, x, y2 + 1, 4); - surface_vline(screen, x, y1, y2, 1); - - x = 60; - - surface_pset(screen, x, y1 - 1, 4); - surface_pset(screen, x, y2 + 1, 4); - surface_vline(screen, x, y2, y1, 2); - - x = 150; y1 = 10; y2 = 100; - - surface_pset(screen, x, y1 - 1, 4); - surface_pset(screen, x, y2 + 1, 4); - surface_vline_f(screen, x, y1, y2, 1); - - getch(); -} - -// draws 4 vertical lines. two are completely outside the bounds of -// the screen and should not be visible at all. the remaining two will be -// partly out of bounds off the top and bottom edges. red pixel markers are -// drawn marking the visible ends of the two partly clipped lines -void test_vline_clipping(void) { - int x, y1, y2; - - surface_clear(screen, 0); - - x = 20; y1 = -32; y2 = 32; - surface_pset(screen, x, y2 + 1, 4); - surface_vline(screen, x, y1, y2, 1); - - x = 270; y1 = 245; y2 = 165; - surface_pset(screen, x, y2 - 1, 4); - surface_vline(screen, x, y1, y2, 2); - - surface_vline(screen, -17, 10, 20, 3); - surface_vline(screen, 400, 100, 300, 5); - - getch(); -} - -// draws a series of lines, both straight and diagonal as well as -// specifying the two line endpoints in either order (e.g. left-right -// and right-left). draws red marker pixels around the end points of each -// line. duplicates of some lines are drawn using the "fast" variant. -void test_line(void) { - int x1, x2, y1, y2; - - surface_clear(screen, 0); - - x1 = 10; y1 = 10; x2 = 20; y2 = 20; - surface_pset(screen, x1 - 1, y1, 4); - surface_pset(screen, x1, y1 - 1, 4); - surface_pset(screen, x2 + 1, y2, 4); - surface_pset(screen, x2, y2 + 1, 4); - surface_line(screen, x1, y1, x2, y2, 1); - - x1 = 10; y1 = 100; x2 = 20; y2 = 150; - surface_pset(screen, x1 - 1, y1, 4); - surface_pset(screen, x1, y1 - 1, 4); - surface_pset(screen, x2 + 1, y2, 4); - surface_pset(screen, x2, y2 + 1, 4); - surface_line(screen, x1, y1, x2, y2, 2); - - x1 = 60; y1 = 150; x2 = 50; y2 = 100; - surface_pset(screen, x1 + 1, y1, 4); - surface_pset(screen, x1, y1 + 1, 4); - surface_pset(screen, x2 - 1, y2, 4); - surface_pset(screen, x2, y2 - 1, 4); - surface_line(screen, x1, y1, x2, y2, 3); - - x1 = 50; y1 = 10; x2 = 100; y2 = 10; - surface_pset(screen, x1 - 1, y1, 4); - surface_pset(screen, x2 + 1, y1, 4); - surface_line(screen, x1, y1, x2, y2, 5); - - x1 = 100; y1 = 50; x2 = 20; y2 = 50; - surface_pset(screen, x1 + 1, y1, 4); - surface_pset(screen, x2 - 1, y1, 4); - surface_line(screen, x1, y1, x2, y2, 6); - - x1 = 290; y1 = 10; x2 = 290; y2 = 100; - surface_pset(screen, x1, y1 - 1, 4); - surface_pset(screen, x2, y2 + 1, 4); - surface_line(screen, x1, y1, x2, y2, 7); - - x1 = 310; y1 = 100; x2 = 310; y2 = 10; - surface_pset(screen, x1, y1 + 1, 4); - surface_pset(screen, x2, y2 - 1, 4); - surface_line(screen, x1, y1, x2, y2, 8); - - - x1 = 30; y1 = 10; x2 = 40; y2 = 20; - surface_pset(screen, x1 - 1, y1, 4); - surface_pset(screen, x1, y1 - 1, 4); - surface_pset(screen, x2 + 1, y2, 4); - surface_pset(screen, x2, y2 + 1, 4); - surface_line_f(screen, x1, y1, x2, y2, 1); - - x1 = 30; y1 = 100; x2 = 40; y2 = 150; - surface_pset(screen, x1 - 1, y1, 4); - surface_pset(screen, x1, y1 - 1, 4); - surface_pset(screen, x2 + 1, y2, 4); - surface_pset(screen, x2, y2 + 1, 4); - surface_line_f(screen, x1, y1, x2, y2, 2); - - x1 = 50; y1 = 20; x2 = 100; y2 = 20; - surface_pset(screen, x1 - 1, y1, 4); - surface_pset(screen, x2 + 1, y1, 4); - surface_line_f(screen, x1, y1, x2, y2, 5); - - x1 = 300; y1 = 10; x2 = 300; y2 = 100; - surface_pset(screen, x1, y1 - 1, 4); - surface_pset(screen, x2, y2 + 1, 4); - surface_line_f(screen, x1, y1, x2, y2, 7); - - getch(); -} - -// draws a series of lines fanned out in a circle originating from the -// center of the screen. each line extends well past the boundaries of the -// screen and so should be partially clipped. additionally, 4 straight lines -// are drawn completely outside the bounds of the screen and should not be -// visible. -void test_line_clipping(void) { - int angle, color; - float x, y; - - surface_clear(screen, 0); - - surface_line(screen, 10, -30, 100, -30, 1); - surface_line(screen, 70, 250, 170, 250, 2); - surface_line(screen, -100, 120, -100, 199, 3); - surface_line(screen, 320, 99, 320, 199, 5); - - for (angle = 0, color = 32; angle <= 360; angle += 10, ++color) { - point_on_circle(400, DEG_TO_RAD(angle), &x, &y); - surface_line(screen, 160, 100, (int)x + 160, (int)y + 100, color); - } - - getch(); -} - -// draws two rectangles. red pixels mark the extents of the rects. a -// duplicate of the first rectangle is drawn using the "fast" variant. -void test_rect(void) { - int x1, y1, x2, y2; - - surface_clear(screen, 0); - - x1 = 10; y1 = 10; x2 = 90; y2 = 90; - surface_pset(screen, x1 - 1, y1, 4); - surface_pset(screen, x1, y1 - 1, 4); - surface_pset(screen, x2 + 1, y1, 4); - surface_pset(screen, x2, y1 - 1, 4); - surface_pset(screen, x1 - 1, y2, 4); - surface_pset(screen, x1, y2 + 1, 4); - surface_pset(screen, x2 + 1, y2, 4); - surface_pset(screen, x2, y2 + 1, 4); - surface_rect(screen, x1, y1, x2, y2, 1); - - x1 = 10; y1 = 110; x2 = 90; y2 = 190; - surface_pset(screen, x1 - 1, y1, 4); - surface_pset(screen, x1, y1 - 1, 4); - surface_pset(screen, x2 + 1, y1, 4); - surface_pset(screen, x2, y1 - 1, 4); - surface_pset(screen, x1 - 1, y2, 4); - surface_pset(screen, x1, y2 + 1, 4); - surface_pset(screen, x2 + 1, y2, 4); - surface_pset(screen, x2, y2 + 1, 4); - surface_rect_f(screen, x1, y1, x2, y2, 1); - - x1 = 190; y1 = 90; x2 = 110; y2 = 10; - surface_pset(screen, x2 - 1, y2, 4); - surface_pset(screen, x2, y2 - 1, 4); - surface_pset(screen, x1 + 1, y2, 4); - surface_pset(screen, x1, y2 - 1, 4); - surface_pset(screen, x2 - 1, y1, 4); - surface_pset(screen, x2, y1 + 1, 4); - surface_pset(screen, x1 + 1, y1, 4); - surface_pset(screen, x1, y1 + 1, 4); - surface_rect(screen, x1, y1, x2, y2, 2); - - getch(); -} - -// draws 4 rects in each of the top-left and bottom-right corners (two in each -// corner will be completely out of bounds, so should not be visible). also, -// two long rects are drawn along the center of the screen and they each -// extend beyond the edges of the screen. red pixels are drawn to mark rect -// extents. -void test_rect_clipping(void) { - int x1, y1, x2, y2; - - surface_clear(screen, 0); - - x1 = -8; y1 = 10; x2 = 7; y2 = 25; - surface_pset(screen, x2, y1 - 1, 4); - surface_pset(screen, x2 + 1, y1, 4); - surface_pset(screen, x2 + 1, y2, 4); - surface_pset(screen, x2, y2 + 1, 4); - surface_rect(screen, x1, y1, x2, y2, 1); - - surface_rect(screen, -16, 30, -1, 46, 10); - - x1 = 20; y1 = -8; x2 = 35; y2 = 7; - surface_pset(screen, x1 - 1, y2, 4); - surface_pset(screen, x1, y2 + 1, 4); - surface_pset(screen, x2 + 1, y2, 4); - surface_pset(screen, x2, y2 + 1, 4); - surface_rect(screen, x1, y1, x2, y2, 2); - - surface_rect(screen, 40, -16, 55, -1, 11); - - x1 = 313; y1 = 170; x2 = 328; y2 = 185; - surface_pset(screen, x1, y1 - 1, 4); - surface_pset(screen, x1 - 1, y1, 4); - surface_pset(screen, x1 - 1, y2, 4); - surface_pset(screen, x1, y2 + 1, 4); - surface_rect(screen, x1, y1, x2, y2, 3); - - surface_rect(screen, 320, 150, 335, 165, 12); - - x1 = 285; y1 = 193; x2 = 300; y2 = 208; - surface_pset(screen, x1 - 1, y1, 4); - surface_pset(screen, x1, y1 - 1, 4); - surface_pset(screen, x2 + 1, y1, 4); - surface_pset(screen, x2, y1 - 1, 4); - surface_rect(screen, x1, y1, x2, y2, 5); - - surface_rect(screen, 265, 200, 280, 215, 13); - - x1 = 150; y1 = -10; x2 = 170; y2 = 210; - surface_pset(screen, x1 - 1, 10, 4); - surface_pset(screen, x2 + 1, 10, 4); - surface_rect(screen, x1, y1, x2, y2, 7); - - x1 = -10; y1 = 90; x2 = 330; y2 = 110; - surface_pset(screen, 10, y1 - 1, 4); - surface_pset(screen, 10, y2 + 1, 4); - surface_rect(screen, x1, y1, x2, y2, 8); - - getch(); -} - -// draws two filled rectangles. red pixels mark the extents of the rects. a -// duplicate of the first rectangle is drawn using the "fast" variant. -void test_filled_rect(void) { - int x1, y1, x2, y2; - - surface_clear(screen, 0); - - x1 = 10; y1 = 10; x2 = 90; y2 = 90; - surface_pset(screen, x1 - 1, y1, 4); - surface_pset(screen, x1, y1 - 1, 4); - surface_pset(screen, x2 + 1, y1, 4); - surface_pset(screen, x2, y1 - 1, 4); - surface_pset(screen, x1 - 1, y2, 4); - surface_pset(screen, x1, y2 + 1, 4); - surface_pset(screen, x2 + 1, y2, 4); - surface_pset(screen, x2, y2 + 1, 4); - surface_filled_rect(screen, x1, y1, x2, y2, 1); - - x1 = 10; y1 = 110; x2 = 90; y2 = 190; - surface_pset(screen, x1 - 1, y1, 4); - surface_pset(screen, x1, y1 - 1, 4); - surface_pset(screen, x2 + 1, y1, 4); - surface_pset(screen, x2, y1 - 1, 4); - surface_pset(screen, x1 - 1, y2, 4); - surface_pset(screen, x1, y2 + 1, 4); - surface_pset(screen, x2 + 1, y2, 4); - surface_pset(screen, x2, y2 + 1, 4); - surface_filled_rect_f(screen, x1, y1, x2, y2, 1); - - x1 = 190; y1 = 90; x2 = 110; y2 = 10; - surface_pset(screen, x2 - 1, y2, 4); - surface_pset(screen, x2, y2 - 1, 4); - surface_pset(screen, x1 + 1, y2, 4); - surface_pset(screen, x1, y2 - 1, 4); - surface_pset(screen, x2 - 1, y1, 4); - surface_pset(screen, x2, y1 + 1, 4); - surface_pset(screen, x1 + 1, y1, 4); - surface_pset(screen, x1, y1 + 1, 4); - surface_filled_rect(screen, x1, y1, x2, y2, 2); - - getch(); -} - -// draws 4 rects in each of the top-left and bottom-right corners (two in each -// corner will be completely out of bounds, so should not be visible). also, -// two long rects are drawn along the center of the screen and they each -// extend beyond the edges of the screen. red pixels are drawn to mark rect -// extents. -void test_filled_rect_clipping(void) { - int x1, y1, x2, y2; - - surface_clear(screen, 0); - - x1 = -8; y1 = 10; x2 = 7; y2 = 25; - surface_pset(screen, x2, y1 - 1, 4); - surface_pset(screen, x2 + 1, y1, 4); - surface_pset(screen, x2 + 1, y2, 4); - surface_pset(screen, x2, y2 + 1, 4); - surface_filled_rect(screen, x1, y1, x2, y2, 1); - - surface_filled_rect(screen, -16, 30, -1, 46, 10); - - x1 = 20; y1 = -8; x2 = 35; y2 = 7; - surface_pset(screen, x1 - 1, y2, 4); - surface_pset(screen, x1, y2 + 1, 4); - surface_pset(screen, x2 + 1, y2, 4); - surface_pset(screen, x2, y2 + 1, 4); - surface_filled_rect(screen, x1, y1, x2, y2, 2); - - surface_filled_rect(screen, 40, -16, 55, -1, 11); - - x1 = 313; y1 = 170; x2 = 328; y2 = 185; - surface_pset(screen, x1, y1 - 1, 4); - surface_pset(screen, x1 - 1, y1, 4); - surface_pset(screen, x1 - 1, y2, 4); - surface_pset(screen, x1, y2 + 1, 4); - surface_filled_rect(screen, x1, y1, x2, y2, 3); - - surface_filled_rect(screen, 320, 150, 335, 165, 12); - - x1 = 285; y1 = 193; x2 = 300; y2 = 208; - surface_pset(screen, x1 - 1, y1, 4); - surface_pset(screen, x1, y1 - 1, 4); - surface_pset(screen, x2 + 1, y1, 4); - surface_pset(screen, x2, y1 - 1, 4); - surface_filled_rect(screen, x1, y1, x2, y2, 5); - - surface_filled_rect(screen, 265, 200, 280, 215, 13); - - x1 = 150; y1 = -10; x2 = 170; y2 = 210; - surface_pset(screen, x1 - 1, 10, 4); - surface_pset(screen, x2 + 1, 10, 4); - surface_filled_rect(screen, x1, y1, x2, y2, 7); - - x1 = -10; y1 = 90; x2 = 330; y2 = 110; - surface_pset(screen, 10, y1 - 1, 4); - surface_pset(screen, 10, y2 + 1, 4); - surface_filled_rect(screen, x1, y1, x2, y2, 8); - - getch(); -} - -// blits a 5-color image in a few different sizes. first two test full -// image blits and partial image blits. remaining 4 blits test the shorthand -// blit function that simply blits the entire source image. -// a duplicate set of blits is done using the "fast" variants. -// the image sizes are chosen to ensure each different internal blitter is run. -void test_blit(void) { - int x, y; - - SURFACE *bmp16 = get_image(16, 16); - SURFACE *bmp12 = get_image(12, 12); - SURFACE *bmp21 = get_image(21, 21); - SURFACE *bmp3 = get_image(3, 3); - - surface_clear(screen, 0); - - x = 0; y = 0; - - surface_blit_region(bmp16, screen, 0, 0, 16, 16, x + 16, y + 16); - surface_blit_region(bmp16, screen, 8, 8, 8, 8, x + 48, y + 16); - - surface_blit(bmp16, screen, x + 16, y + 48); - surface_blit(bmp12, screen, x + 48, y + 48); - surface_blit(bmp21, screen, x + 80, y + 48); - surface_blit(bmp3, screen, x + 112, y + 48); - - x = 160; y = 0; - - surface_blit_region_f(bmp16, screen, 0, 0, 16, 16, x + 16, y + 16); - surface_blit_region_f(bmp16, screen, 8, 8, 8, 8, x + 48, y + 16); - - surface_blit_f(bmp16, screen, x + 16, y + 48); - surface_blit_f(bmp12, screen, x + 48, y + 48); - surface_blit_f(bmp21, screen, x + 80, y + 48); - surface_blit_f(bmp3, screen, x + 112, y + 48); - - surface_free(bmp16); - surface_free(bmp12); - surface_free(bmp21); - surface_free(bmp3); - getch(); -} - -// performs 7 blits along each edge of the screen, clipping the image by -// varying amounts. the 7th blit on each edge is completely out of bounds and -// should not be visible at all. -void test_blit_clipping(void) { - SURFACE *bmp = get_image(16, 16); - - surface_clear(screen, 0); - - surface_blit(bmp, screen, -3, 16); - surface_blit(bmp, screen, -4, 36); - surface_blit(bmp, screen, -8, 56); - surface_blit(bmp, screen, -12, 76); - surface_blit(bmp, screen, -13, 96); - surface_blit(bmp, screen, -14, 116); - surface_blit(bmp, screen, -16, 136); - - surface_blit(bmp, screen, 16, -3); - surface_blit(bmp, screen, 36, -4); - surface_blit(bmp, screen, 56, -8); - surface_blit(bmp, screen, 76, -12); - surface_blit(bmp, screen, 96, -13); - surface_blit(bmp, screen, 116, -14); - surface_blit(bmp, screen, 136, -16); - - surface_blit(bmp, screen, 307, 16); - surface_blit(bmp, screen, 308, 36); - surface_blit(bmp, screen, 312, 56); - surface_blit(bmp, screen, 316, 76); - surface_blit(bmp, screen, 317, 96); - surface_blit(bmp, screen, 318, 116); - surface_blit(bmp, screen, 320, 136); - - surface_blit(bmp, screen, 16, 187); - surface_blit(bmp, screen, 36, 188); - surface_blit(bmp, screen, 56, 192); - surface_blit(bmp, screen, 76, 196); - surface_blit(bmp, screen, 96, 197); - surface_blit(bmp, screen, 116, 198); - surface_blit(bmp, screen, 136, 200); - - surface_free(bmp); - getch(); -} - -// basically the exact same test as test_blit(), but uses sprite blitting -// instead and uses a grey background. no part of the screen buffer should be -// black as that colour is not used anywhere in the test sprite. -void test_sprite(void) { - int x, y; - SURFACE *bmp16 = get_sprite(16, 16); - SURFACE *bmp12 = get_sprite(12, 12); - SURFACE *bmp21 = get_sprite(21, 21); - SURFACE *bmp3 = get_sprite(3, 3); - - surface_clear(screen, 8); - - x = 0; y = 0; - - surface_blit_sprite_region(bmp16, screen, 0, 0, 16, 16, x + 16, y + 16); - surface_blit_sprite_region(bmp16, screen, 8, 8, 8, 8, x + 48, y + 16); - - surface_blit_sprite(bmp16, screen, x + 16, y + 48); - surface_blit_sprite(bmp12, screen, x + 48, y + 48); - surface_blit_sprite(bmp21, screen, x + 80, y + 48); - surface_blit_sprite(bmp3, screen, x + 112, y + 48); - - x = 160; y = 0; - - surface_blit_sprite_region_f(bmp16, screen, 0, 0, 16, 16, x + 16, y + 16); - surface_blit_sprite_region_f(bmp16, screen, 8, 8, 8, 8, x + 48, y + 16); - - surface_blit_sprite_f(bmp16, screen, x + 16, y + 48); - surface_blit_sprite_f(bmp12, screen, x + 48, y + 48); - surface_blit_sprite_f(bmp21, screen, x + 80, y + 48); - surface_blit_sprite_f(bmp3, screen, x + 112, y + 48); - - surface_free(bmp16); - surface_free(bmp12); - surface_free(bmp21); - surface_free(bmp3); - getch(); -} - -// basically the exact same test as test_blit_clipping(), but uses sprite -// blitting instead and uses a grey background. no part of the screen buffer -// should be black as that colour is not used anywhere in the test sprite. -void test_sprite_clipping(void) { - SURFACE *bmp = get_sprite(16, 16); - - surface_clear(screen, 8); - - surface_blit_sprite(bmp, screen, -3, 16); - surface_blit_sprite(bmp, screen, -4, 36); - surface_blit_sprite(bmp, screen, -8, 56); - surface_blit_sprite(bmp, screen, -12, 76); - surface_blit_sprite(bmp, screen, -13, 96); - surface_blit_sprite(bmp, screen, -14, 116); - surface_blit_sprite(bmp, screen, -16, 136); - - surface_blit_sprite(bmp, screen, 16, -3); - surface_blit_sprite(bmp, screen, 36, -4); - surface_blit_sprite(bmp, screen, 56, -8); - surface_blit_sprite(bmp, screen, 76, -12); - surface_blit_sprite(bmp, screen, 96, -13); - surface_blit_sprite(bmp, screen, 116, -14); - surface_blit_sprite(bmp, screen, 136, -16); - - surface_blit_sprite(bmp, screen, 307, 16); - surface_blit_sprite(bmp, screen, 308, 36); - surface_blit_sprite(bmp, screen, 312, 56); - surface_blit_sprite(bmp, screen, 316, 76); - surface_blit_sprite(bmp, screen, 317, 96); - surface_blit_sprite(bmp, screen, 318, 116); - surface_blit_sprite(bmp, screen, 320, 136); - - surface_blit_sprite(bmp, screen, 16, 187); - surface_blit_sprite(bmp, screen, 36, 188); - surface_blit_sprite(bmp, screen, 56, 192); - surface_blit_sprite(bmp, screen, 76, 196); - surface_blit_sprite(bmp, screen, 96, 197); - surface_blit_sprite(bmp, screen, 116, 198); - surface_blit_sprite(bmp, screen, 136, 200); - - surface_free(bmp); - getch(); -} - -// prints out some simple text messages, including ones with newlines in them. -// also prints out the entire 1-127 ASCII character set in a 16x8 grid. -// a duplicate set of text is drawn using the "fast" variants. -void test_text(void) { - int i, x, y; - char string[255]; - char *p; - - surface_clear(screen, 0); - memset(string, 0, 255); - - surface_text(screen, 10, 10, 15, "Hello, world!"); - surface_text_f(screen, 170, 10, 15, "Hello, world!"); - - surface_filled_rect(screen, 8, 28, 114, 40, 7); - surface_text(screen, 10, 30, 15, "transparency!"); - surface_filled_rect_f(screen, 168, 28, 274, 40, 7); - surface_text_f(screen, 170, 30, 15, "transparency!"); - - surface_text(screen, 10, 50, 15, "line 1\nline 2"); - surface_text_f(screen, 170, 50, 15, "line 1\nline 2"); - - surface_printf(screen, 10, 70, 15, "printf pi %.5f", PI); - surface_printf_f(screen, 170, 70, 15, "printf pi %.5f", PI); - - p = &string[0]; - for (i = 1; i <= 127; ++i, ++p) { - if (i % 16 == 0) { - *p = '\n'; - ++p; - } - if (i == 10) - *p = ' '; // will be interpreted as a \n (and hence, not shown) - else - *p = (char)i; - } - - surface_text(screen, 10, 100, 15, string); - surface_text_f(screen, 170, 100, 15, string); - - getch(); -} - -// text is drawn along each edge of the screen. two messages are drawn at each -// edge, but one is completely out of bounds so the second should not be -// visible. red rects are drawn marking the extents of the text. -void test_text_clipping(void) { - int x, y; - char message[] = "Hello, world!"; - int len = strlen(message); - int width = len * 8; - int height = 8; - - surface_clear(screen, 0); - - x = -32; y = 10; - surface_rect(screen, x - 1, y - 1, x + width, y + height, 4); - surface_text(screen, x, y, 9, message); - - x = 80; y = -4; - surface_rect(screen, x - 1, y - 1, x + width, y + height, 4); - surface_text(screen, x, y, 10, message); - - x = 288; y = 120; - surface_rect(screen, x - 1, y - 1, x + width, y + height, 4); - surface_text(screen, x, y, 11, message); - - x = 200; y = 196; - surface_rect(screen, x - 1, y - 1, x + width, y + height, 4); - surface_text(screen, x, y, 12, message); - - x = -232; y = 10; - surface_rect(screen, x - 1, y - 1, x + width, y + height, 4); - surface_text(screen, x, y, 5, message); - - x = 80; y = -24; - surface_rect(screen, x - 1, y - 1, x + width, y + height, 4); - surface_text(screen, x, y, 6, message); - - x = 360; y = 120; - surface_rect(screen, x - 1, y - 1, x + width, y + height, 4); - surface_text(screen, x, y, 7, message); - - x = 200; y = 240; - surface_rect(screen, x - 1, y - 1, x + width, y + height, 4); - surface_text(screen, x, y, 8, message); - - getch(); -} - -// displays the entire palette in a grid, waits for a keypress, then changes -// color 15's RGB values. -void test_palette(void) { - int i, x, y; - byte r, g, b; - - surface_clear(screen, 0); - - i = 0; - for (y = 0; y < 16; ++y) { - for (x = 0; x < 16; ++x) { - surface_filled_rect(screen, x * 8, y * 8, x * 8 + 7, y * 8 + 7, i); - ++i; - } - } - - getch(); - - pal_get_color(15, &r, &g, &b); - ASSERT(r == 63 && g == 63 && b == 63); - pal_set_color(15, r / 2, g / 2, b / 2); - - getch(); - pal_set_color(15, r, g, b); -} - -void test_palette_fading(void) { - int i, x, y; - byte palette[768]; - surface_clear(screen, 0); - - i = 0; - for (y = 0; y < 16; ++y) { - for (x = 0; x < 16; ++x) { - surface_filled_rect(screen, x * 8, y * 8, x * 8 + 7, y * 8 + 7, i); - ++i; - } - } - pal_get(palette); - - getch(); - - pal_fade_range_to_color(16, 31, 0, 0, 0, 1); - - getch(); - - pal_fade_range_to_palette(16, 31, palette, 1); - - getch(); - - pal_fade_to_color(0, 0, 0, 1); - - getch(); - - pal_fade_to_palette(palette, 1); - - getch(); -} - -void test_pcx(void) { - SURFACE *pcx; - DGL_ERROR err; - byte pcx_palette[768]; - byte original_palette[768]; - - surface_clear(screen, 0); - pal_get(original_palette); - - pcx = pcx_load("notreal.pcx", NULL); - err = dgl_last_error(); - ASSERT(pcx == NULL); - ASSERT(err != DGL_NONE); - - pcx = pcx_load("test.pcx", NULL); - ASSERT(pcx != NULL); - - surface_blit(pcx, screen, 0, 0); - getch(); - - surface_clear(screen, 0); - surface_free(pcx); - pcx = pcx_load("test.pcx", pcx_palette); - ASSERT(pcx != NULL); - - pal_set(pcx_palette); - surface_blit(pcx, screen, 0, 0); - - getch(); - pal_set(original_palette); -} - -// --------------------------------------------------------------------------- - -int main(void) { - signal(SIGINT, break_handler); - - dgl_init(); - - ASSERT(screen == NULL); - - if (!video_init()) { - printf("Error initializing video: %s\n", dgl_last_error_message()); - return 1; - } - - ASSERT(screen != NULL); - ASSERT(screen->width == 320 && screen->height == 200); - - backbuffer = surface_create(320, 200); - ASSERT(backbuffer != NULL); - ASSERT(backbuffer->width == 320 && backbuffer->height == 200); - - test_fixed(); - test_vector2i(); - test_vector2f(); - test_surface_clear(); - test_surface_copy(); - test_pixels_1(); - test_pixels_2(); - test_pixels_clipping(); - test_hline(); - test_hline_clipping(); - test_vline(); - test_vline_clipping(); - test_line(); - test_line_clipping(); - test_rect(); - test_rect_clipping(); - test_filled_rect(); - test_filled_rect_clipping(); - test_blit(); - test_blit_clipping(); - test_sprite(); - test_sprite_clipping(); - test_text(); - test_text_clipping(); - test_palette(); - test_palette_fading(); - test_pcx(); - - surface_free(backbuffer); - - - return 0; -} - diff --git a/TEST/BLIT.C b/TEST/BLIT.C new file mode 100644 index 0000000..359c33b --- /dev/null +++ b/TEST/BLIT.C @@ -0,0 +1,210 @@ +#include "blit.h" +#include "dgl.h" +#include +#include "helpers.h" + +SURFACE* get_sprite(int width, int height) { + int x_third, y_third; + SURFACE *sprite = surface_create(width, height); + ASSERT(sprite != NULL); + ASSERT(sprite->width == width); + ASSERT(sprite->height == height); + + x_third = width / 3; + y_third = height / 3; + + surface_filled_rect(sprite, 0, 0, x_third, y_third, 1); + surface_filled_rect(sprite, x_third * 2, y_third * 2, width - 1, height - 1, 2); + surface_filled_rect(sprite, 0, (y_third * 2), x_third, height - 1, 3); + surface_filled_rect(sprite, x_third * 2, 0, width - 1, y_third, 4); + surface_filled_rect(sprite, x_third, y_third, x_third * 2, y_third * 2, 5); + surface_rect(sprite, 0, 0, width - 1, height - 1, 6); + + return sprite; +} + +SURFACE* get_image(int width, int height) { + int x, y; + SURFACE *image = surface_create(width, height); + ASSERT(image != NULL); + ASSERT(image->width == width); + ASSERT(image->height == height); + + surface_filled_rect(image, 0, 0, width / 2, height / 2, 1); + surface_filled_rect(image, width / 2, 0, width - 1, height / 2, 2); + surface_filled_rect(image, 0, height / 2, width / 2, height - 1, 3); + surface_filled_rect(image, width / 2, height / 2, width - 1, height - 1, 4); + surface_rect(image, 0, 0, width - 1, height - 1, 5); + + return image; +} + +// blits a 5-color image in a few different sizes. first two test full +// image blits and partial image blits. remaining 4 blits test the shorthand +// blit function that simply blits the entire source image. +// a duplicate set of blits is done using the "fast" variants. +// the image sizes are chosen to ensure each different internal blitter is run. +void test_blit(void) { + int x, y; + + SURFACE *bmp16 = get_image(16, 16); + SURFACE *bmp12 = get_image(12, 12); + SURFACE *bmp21 = get_image(21, 21); + SURFACE *bmp3 = get_image(3, 3); + + surface_clear(screen, 0); + + x = 0; y = 0; + + surface_blit_region(bmp16, screen, 0, 0, 16, 16, x + 16, y + 16); + surface_blit_region(bmp16, screen, 8, 8, 8, 8, x + 48, y + 16); + + surface_blit(bmp16, screen, x + 16, y + 48); + surface_blit(bmp12, screen, x + 48, y + 48); + surface_blit(bmp21, screen, x + 80, y + 48); + surface_blit(bmp3, screen, x + 112, y + 48); + + x = 160; y = 0; + + surface_blit_region_f(bmp16, screen, 0, 0, 16, 16, x + 16, y + 16); + surface_blit_region_f(bmp16, screen, 8, 8, 8, 8, x + 48, y + 16); + + surface_blit_f(bmp16, screen, x + 16, y + 48); + surface_blit_f(bmp12, screen, x + 48, y + 48); + surface_blit_f(bmp21, screen, x + 80, y + 48); + surface_blit_f(bmp3, screen, x + 112, y + 48); + + surface_free(bmp16); + surface_free(bmp12); + surface_free(bmp21); + surface_free(bmp3); + getch(); +} + +// performs 7 blits along each edge of the screen, clipping the image by +// varying amounts. the 7th blit on each edge is completely out of bounds and +// should not be visible at all. +void test_blit_clipping(void) { + SURFACE *bmp = get_image(16, 16); + + surface_clear(screen, 0); + + surface_blit(bmp, screen, -3, 16); + surface_blit(bmp, screen, -4, 36); + surface_blit(bmp, screen, -8, 56); + surface_blit(bmp, screen, -12, 76); + surface_blit(bmp, screen, -13, 96); + surface_blit(bmp, screen, -14, 116); + surface_blit(bmp, screen, -16, 136); + + surface_blit(bmp, screen, 16, -3); + surface_blit(bmp, screen, 36, -4); + surface_blit(bmp, screen, 56, -8); + surface_blit(bmp, screen, 76, -12); + surface_blit(bmp, screen, 96, -13); + surface_blit(bmp, screen, 116, -14); + surface_blit(bmp, screen, 136, -16); + + surface_blit(bmp, screen, 307, 16); + surface_blit(bmp, screen, 308, 36); + surface_blit(bmp, screen, 312, 56); + surface_blit(bmp, screen, 316, 76); + surface_blit(bmp, screen, 317, 96); + surface_blit(bmp, screen, 318, 116); + surface_blit(bmp, screen, 320, 136); + + surface_blit(bmp, screen, 16, 187); + surface_blit(bmp, screen, 36, 188); + surface_blit(bmp, screen, 56, 192); + surface_blit(bmp, screen, 76, 196); + surface_blit(bmp, screen, 96, 197); + surface_blit(bmp, screen, 116, 198); + surface_blit(bmp, screen, 136, 200); + + surface_free(bmp); + getch(); +} + +// basically the exact same test as test_blit(), but uses sprite blitting +// instead and uses a grey background. no part of the screen buffer should be +// black as that colour is not used anywhere in the test sprite. +void test_sprite(void) { + int x, y; + SURFACE *bmp16 = get_sprite(16, 16); + SURFACE *bmp12 = get_sprite(12, 12); + SURFACE *bmp21 = get_sprite(21, 21); + SURFACE *bmp3 = get_sprite(3, 3); + + surface_clear(screen, 8); + + x = 0; y = 0; + + surface_blit_sprite_region(bmp16, screen, 0, 0, 16, 16, x + 16, y + 16); + surface_blit_sprite_region(bmp16, screen, 8, 8, 8, 8, x + 48, y + 16); + + surface_blit_sprite(bmp16, screen, x + 16, y + 48); + surface_blit_sprite(bmp12, screen, x + 48, y + 48); + surface_blit_sprite(bmp21, screen, x + 80, y + 48); + surface_blit_sprite(bmp3, screen, x + 112, y + 48); + + x = 160; y = 0; + + surface_blit_sprite_region_f(bmp16, screen, 0, 0, 16, 16, x + 16, y + 16); + surface_blit_sprite_region_f(bmp16, screen, 8, 8, 8, 8, x + 48, y + 16); + + surface_blit_sprite_f(bmp16, screen, x + 16, y + 48); + surface_blit_sprite_f(bmp12, screen, x + 48, y + 48); + surface_blit_sprite_f(bmp21, screen, x + 80, y + 48); + surface_blit_sprite_f(bmp3, screen, x + 112, y + 48); + + surface_free(bmp16); + surface_free(bmp12); + surface_free(bmp21); + surface_free(bmp3); + getch(); +} + +// basically the exact same test as test_blit_clipping(), but uses sprite +// blitting instead and uses a grey background. no part of the screen buffer +// should be black as that colour is not used anywhere in the test sprite. +void test_sprite_clipping(void) { + SURFACE *bmp = get_sprite(16, 16); + + surface_clear(screen, 8); + + surface_blit_sprite(bmp, screen, -3, 16); + surface_blit_sprite(bmp, screen, -4, 36); + surface_blit_sprite(bmp, screen, -8, 56); + surface_blit_sprite(bmp, screen, -12, 76); + surface_blit_sprite(bmp, screen, -13, 96); + surface_blit_sprite(bmp, screen, -14, 116); + surface_blit_sprite(bmp, screen, -16, 136); + + surface_blit_sprite(bmp, screen, 16, -3); + surface_blit_sprite(bmp, screen, 36, -4); + surface_blit_sprite(bmp, screen, 56, -8); + surface_blit_sprite(bmp, screen, 76, -12); + surface_blit_sprite(bmp, screen, 96, -13); + surface_blit_sprite(bmp, screen, 116, -14); + surface_blit_sprite(bmp, screen, 136, -16); + + surface_blit_sprite(bmp, screen, 307, 16); + surface_blit_sprite(bmp, screen, 308, 36); + surface_blit_sprite(bmp, screen, 312, 56); + surface_blit_sprite(bmp, screen, 316, 76); + surface_blit_sprite(bmp, screen, 317, 96); + surface_blit_sprite(bmp, screen, 318, 116); + surface_blit_sprite(bmp, screen, 320, 136); + + surface_blit_sprite(bmp, screen, 16, 187); + surface_blit_sprite(bmp, screen, 36, 188); + surface_blit_sprite(bmp, screen, 56, 192); + surface_blit_sprite(bmp, screen, 76, 196); + surface_blit_sprite(bmp, screen, 96, 197); + surface_blit_sprite(bmp, screen, 116, 198); + surface_blit_sprite(bmp, screen, 136, 200); + + surface_free(bmp); + getch(); +} + diff --git a/TEST/BLIT.H b/TEST/BLIT.H new file mode 100644 index 0000000..481ab6a --- /dev/null +++ b/TEST/BLIT.H @@ -0,0 +1,10 @@ +#ifndef DGL_TEST_BLIT_H_INCLUDED +#define DGL_TEST_BLIT_H_INCLUDED + +void test_blit(void); +void test_blit_clipping(void); +void test_sprite(void); +void test_sprite_clipping(void); + +#endif + diff --git a/TEST/FIXED.C b/TEST/FIXED.C new file mode 100644 index 0000000..46e06d9 --- /dev/null +++ b/TEST/FIXED.C @@ -0,0 +1,69 @@ +#include "fixed.h" +#include "dgl.h" +#include +#include "helpers.h" + +void test_fixed(void) { + fixed a, b, c; + float af, bf, cf, f; + int i; + + a = FTOFIX(PI); + f = FIXTOF(a); + ASSERT(FFIX_EQU(PI, f)); + + a = FTOFIX(-0.37f); + f = FIXTOF(a); + ASSERT(FFIX_EQU(-0.38f, f)); + + a = ITOFIX(17); + i = FIXTOI(a); + ASSERT(17 == i); + + a = ITOFIX(-17); + i = FIXTOI(a); + ASSERT(-17 == i); + + a = FTOFIX(1.5f); + b = FTOFIX(2.3f); + c = a + b; + f = FIXTOF(c); + ASSERT(FFIX_EQU((1.5f + 2.3f), f)); + + a = FTOFIX(0.2f); + b = FTOFIX(1.7f); + c = a - b; + f = FIXTOF(c); + ASSERT(FFIX_EQU((0.2f - 1.7f), f)); + + a = FTOFIX(16.0f); + c = a >> 2; + f = FIXTOF(c); + ASSERT(FFIX_EQU((16 >> 2), f)); + + a = FTOFIX(7.1f); + b = ITOFIX(2); + c = fix_mul(a, b); + f = FIXTOF(c); + ASSERT(FFIX_EQU((7.1f * 2), f)); + + a = FTOFIX(77.7f); + b = ITOFIX(3); + c = fix_div(a, b); + f = FIXTOF(c); + ASSERT(FFIX_EQU((77.7f / 3), f)); + + for (i = 0; i <= 360; i += 45) { + f = DEG_TO_RAD(i + 1); + a = fix_sin(FTOFIX(f)); + af = sin(f); + b = fix_cos(FTOFIX(f)); + bf = cos(f); + c = fix_tan(FTOFIX(f)); + cf = tan(f); + ASSERT(FFIX_EQU(FIXTOF(a), af)); + ASSERT(FFIX_EQU(FIXTOF(b), bf)); + ASSERT(FFIX_EQU(FIXTOF(c), cf)); + } +} + diff --git a/TEST/FIXED.H b/TEST/FIXED.H new file mode 100644 index 0000000..6cca239 --- /dev/null +++ b/TEST/FIXED.H @@ -0,0 +1,7 @@ +#ifndef DGL_TEST_FIXED_H_INCLUDED +#define DGL_TEST_FIXED_H_INCLUDED + +void test_fixed(void); + +#endif + diff --git a/TEST/HELPERS.H b/TEST/HELPERS.H new file mode 100644 index 0000000..d33f988 --- /dev/null +++ b/TEST/HELPERS.H @@ -0,0 +1,24 @@ +#ifndef DGL_TEST_HELPERS_H_INCLUDED +#define DGL_TEST_HELPERS_H_INCLUDED + +#include +#include +#include "dgl.h" + +#define F_EQU(a, b) (close_enough((a), (b), TOLERANCE)) +#define FFIX_EQU(a, b) (close_enough((a), (b), 0.01f)) + +extern void _breakpoint(); +#pragma aux _breakpoint = "int 0x03"; + + +#define ASSERT(x) \ + do { \ + if (!(x)) { \ + printf("Assertion failed at %s:%d, %s\n", __FILE__, __LINE__, #x); \ + _breakpoint(); \ + } \ + } while (0) + +#endif + diff --git a/TEST/LINE.C b/TEST/LINE.C new file mode 100644 index 0000000..026dfe2 --- /dev/null +++ b/TEST/LINE.C @@ -0,0 +1,208 @@ +#include "line.h" +#include "dgl.h" +#include + +// draws two horizontal lines, with red pixels marking the extents of the +// lines. a third line is drawn using the "fast" variant. +void test_hline(void) { + int x1, x2, y; + + surface_clear(screen, 0); + + x1 = 10; x2 = 100; y = 20; + + surface_pset(screen, x1 - 1, y, 4); + surface_pset(screen, x2 + 1, y, 4); + surface_hline(screen, x1, x2, y, 1); + + y = 30; + + surface_pset(screen, x1 - 1, y, 4); + surface_pset(screen, x2 + 1, y, 4); + surface_hline(screen, x2, x1, y, 2); + + x1 = 200; x2 = 300; y = 20; + + surface_pset(screen, x1 - 1, y, 4); + surface_pset(screen, x2 + 1, y, 4); + surface_hline_f(screen, x1, x2, y, 1); + + getch(); +} + +// draws 4 horizontal lines. two are completely outside the bounds of +// the screen and should not be visible at all. the remaining two will be +// partly out of bounds off the left and right edges. red pixel markers are +// drawn marking the visible ends of the two partly clipped lines +void test_hline_clipping(void) { + int x1, x2, y; + + surface_clear(screen, 0); + + x1 = -50; x2 = 50; y = 6; + surface_pset(screen, x2 + 1, y, 4); + surface_hline(screen, x1, x2, y, 1); + + x1 = 300; x2 = 340; y = 130; + surface_pset(screen, x1 - 1, y, 4); + surface_hline(screen, x1, x2, y, 2); + + surface_hline(screen, 100, 200, -10, 3); + surface_hline(screen, 20, 80, 250, 5); + + getch(); +} + +// draws two vertical lines, with red pixels marking the extents of +// the lines. a third line is drawn using the "fast" variant. +void test_vline(void) { + int x, y1, y2; + + surface_clear(screen, 0); + + x = 50; y1 = 10; y2 = 100; + + surface_pset(screen, x, y1 - 1, 4); + surface_pset(screen, x, y2 + 1, 4); + surface_vline(screen, x, y1, y2, 1); + + x = 60; + + surface_pset(screen, x, y1 - 1, 4); + surface_pset(screen, x, y2 + 1, 4); + surface_vline(screen, x, y2, y1, 2); + + x = 150; y1 = 10; y2 = 100; + + surface_pset(screen, x, y1 - 1, 4); + surface_pset(screen, x, y2 + 1, 4); + surface_vline_f(screen, x, y1, y2, 1); + + getch(); +} + +// draws 4 vertical lines. two are completely outside the bounds of +// the screen and should not be visible at all. the remaining two will be +// partly out of bounds off the top and bottom edges. red pixel markers are +// drawn marking the visible ends of the two partly clipped lines +void test_vline_clipping(void) { + int x, y1, y2; + + surface_clear(screen, 0); + + x = 20; y1 = -32; y2 = 32; + surface_pset(screen, x, y2 + 1, 4); + surface_vline(screen, x, y1, y2, 1); + + x = 270; y1 = 245; y2 = 165; + surface_pset(screen, x, y2 - 1, 4); + surface_vline(screen, x, y1, y2, 2); + + surface_vline(screen, -17, 10, 20, 3); + surface_vline(screen, 400, 100, 300, 5); + + getch(); +} + +// draws a series of lines, both straight and diagonal as well as +// specifying the two line endpoints in either order (e.g. left-right +// and right-left). draws red marker pixels around the end points of each +// line. duplicates of some lines are drawn using the "fast" variant. +void test_line(void) { + int x1, x2, y1, y2; + + surface_clear(screen, 0); + + x1 = 10; y1 = 10; x2 = 20; y2 = 20; + surface_pset(screen, x1 - 1, y1, 4); + surface_pset(screen, x1, y1 - 1, 4); + surface_pset(screen, x2 + 1, y2, 4); + surface_pset(screen, x2, y2 + 1, 4); + surface_line(screen, x1, y1, x2, y2, 1); + + x1 = 10; y1 = 100; x2 = 20; y2 = 150; + surface_pset(screen, x1 - 1, y1, 4); + surface_pset(screen, x1, y1 - 1, 4); + surface_pset(screen, x2 + 1, y2, 4); + surface_pset(screen, x2, y2 + 1, 4); + surface_line(screen, x1, y1, x2, y2, 2); + + x1 = 60; y1 = 150; x2 = 50; y2 = 100; + surface_pset(screen, x1 + 1, y1, 4); + surface_pset(screen, x1, y1 + 1, 4); + surface_pset(screen, x2 - 1, y2, 4); + surface_pset(screen, x2, y2 - 1, 4); + surface_line(screen, x1, y1, x2, y2, 3); + + x1 = 50; y1 = 10; x2 = 100; y2 = 10; + surface_pset(screen, x1 - 1, y1, 4); + surface_pset(screen, x2 + 1, y1, 4); + surface_line(screen, x1, y1, x2, y2, 5); + + x1 = 100; y1 = 50; x2 = 20; y2 = 50; + surface_pset(screen, x1 + 1, y1, 4); + surface_pset(screen, x2 - 1, y1, 4); + surface_line(screen, x1, y1, x2, y2, 6); + + x1 = 290; y1 = 10; x2 = 290; y2 = 100; + surface_pset(screen, x1, y1 - 1, 4); + surface_pset(screen, x2, y2 + 1, 4); + surface_line(screen, x1, y1, x2, y2, 7); + + x1 = 310; y1 = 100; x2 = 310; y2 = 10; + surface_pset(screen, x1, y1 + 1, 4); + surface_pset(screen, x2, y2 - 1, 4); + surface_line(screen, x1, y1, x2, y2, 8); + + + x1 = 30; y1 = 10; x2 = 40; y2 = 20; + surface_pset(screen, x1 - 1, y1, 4); + surface_pset(screen, x1, y1 - 1, 4); + surface_pset(screen, x2 + 1, y2, 4); + surface_pset(screen, x2, y2 + 1, 4); + surface_line_f(screen, x1, y1, x2, y2, 1); + + x1 = 30; y1 = 100; x2 = 40; y2 = 150; + surface_pset(screen, x1 - 1, y1, 4); + surface_pset(screen, x1, y1 - 1, 4); + surface_pset(screen, x2 + 1, y2, 4); + surface_pset(screen, x2, y2 + 1, 4); + surface_line_f(screen, x1, y1, x2, y2, 2); + + x1 = 50; y1 = 20; x2 = 100; y2 = 20; + surface_pset(screen, x1 - 1, y1, 4); + surface_pset(screen, x2 + 1, y1, 4); + surface_line_f(screen, x1, y1, x2, y2, 5); + + x1 = 300; y1 = 10; x2 = 300; y2 = 100; + surface_pset(screen, x1, y1 - 1, 4); + surface_pset(screen, x2, y2 + 1, 4); + surface_line_f(screen, x1, y1, x2, y2, 7); + + getch(); +} + +// draws a series of lines fanned out in a circle originating from the +// center of the screen. each line extends well past the boundaries of the +// screen and so should be partially clipped. additionally, 4 straight lines +// are drawn completely outside the bounds of the screen and should not be +// visible. +void test_line_clipping(void) { + int angle, color; + float x, y; + + surface_clear(screen, 0); + + surface_line(screen, 10, -30, 100, -30, 1); + surface_line(screen, 70, 250, 170, 250, 2); + surface_line(screen, -100, 120, -100, 199, 3); + surface_line(screen, 320, 99, 320, 199, 5); + + for (angle = 0, color = 32; angle <= 360; angle += 10, ++color) { + point_on_circle(400, DEG_TO_RAD(angle), &x, &y); + surface_line(screen, 160, 100, (int)x + 160, (int)y + 100, color); + } + + getch(); +} + diff --git a/TEST/LINE.H b/TEST/LINE.H new file mode 100644 index 0000000..f3c7147 --- /dev/null +++ b/TEST/LINE.H @@ -0,0 +1,12 @@ +#ifndef DGL_TEST_LINE_H_INCLUDED +#define DGL_TEST_LINE_H_INCLUDED + +void test_hline(void); +void test_hline_clipping(void); +void test_vline(void); +void test_vline_clipping(void); +void test_line(void); +void test_line_clipping(void); + +#endif + diff --git a/TEST/MAKEFILE b/TEST/MAKEFILE new file mode 100644 index 0000000..682e55c --- /dev/null +++ b/TEST/MAKEFILE @@ -0,0 +1,57 @@ +target_config = debug + +target_name = test + +object_files = blit.obj & + fixed.obj & + line.obj & + pal.obj & + pcx.obj & + pset.obj & + rect.obj & + surface.obj & + test.obj & + text.obj & + vector2.obj + + +cc_flags_debug = /d2 /zp4 /5r /fp3 /j +cc_flags_release = /d1+ /zp4 /5r /fp3 /onatx /oe=40 /j +cc_flags = /mf /i=.. $(cc_flags_$(target_config)) + +link_flags_debug = debug all +link_flags_release = debug all +link_flags = $(link_flags_$(target_config)) + +.c.obj: .AUTODEPEND + wcc386 $[. /zq $(cc_flags) + +$(target_name).lnk: $(object_files) + %create $^@ + %append $^@ NAME $(target_name).exe + %append $^@ SYSTEM DOS4G + %append $^@ OPTION QUIET + %append $^@ OPTION STACK=16k + %append $^@ LIBRARY ..\dgl.lib + @for %i in ($(object_files)) do %append $^@ FILE %i + +$(target_name).exe: $(object_files) $(target_name).lnk + wlink $(link_flags) @$(target_name).lnk + +clean : .SYMBOLIC + del *.obj + del *.err + del $(target_name).exe + del $(target_name).lnk + +.NOCHECK +build : $(target_name).exe + +.NOCHECK +run : $(target_name).exe + $(target_name).exe + +.NOCHECK +debug : $(target_name).exe + wd /swap /trap=rsi $(target_name).exe + diff --git a/TEST/PAL.C b/TEST/PAL.C new file mode 100644 index 0000000..e29bb87 --- /dev/null +++ b/TEST/PAL.C @@ -0,0 +1,64 @@ +#include "pal.h" +#include "dgl.h" +#include +#include "helpers.h" + +// displays the entire palette in a grid, waits for a keypress, then changes +// color 15's RGB values. +void test_palette(void) { + int i, x, y; + byte r, g, b; + + surface_clear(screen, 0); + + i = 0; + for (y = 0; y < 16; ++y) { + for (x = 0; x < 16; ++x) { + surface_filled_rect(screen, x * 8, y * 8, x * 8 + 7, y * 8 + 7, i); + ++i; + } + } + + getch(); + + pal_get_color(15, &r, &g, &b); + ASSERT(r == 63 && g == 63 && b == 63); + pal_set_color(15, r / 2, g / 2, b / 2); + + getch(); + pal_set_color(15, r, g, b); +} + +void test_palette_fading(void) { + int i, x, y; + byte palette[768]; + surface_clear(screen, 0); + + i = 0; + for (y = 0; y < 16; ++y) { + for (x = 0; x < 16; ++x) { + surface_filled_rect(screen, x * 8, y * 8, x * 8 + 7, y * 8 + 7, i); + ++i; + } + } + pal_get(palette); + + getch(); + + pal_fade_range_to_color(16, 31, 0, 0, 0, 1); + + getch(); + + pal_fade_range_to_palette(16, 31, palette, 1); + + getch(); + + pal_fade_to_color(0, 0, 0, 1); + + getch(); + + pal_fade_to_palette(palette, 1); + + getch(); +} + diff --git a/TEST/PAL.H b/TEST/PAL.H new file mode 100644 index 0000000..f3f8956 --- /dev/null +++ b/TEST/PAL.H @@ -0,0 +1,8 @@ +#ifndef DGL_TEST_PAL_H_INCLUDED +#define DGL_TEST_PAL_H_INCLUDED + +void test_palette(void); +void test_palette_fading(void); + +#endif + diff --git a/TEST/PCX.C b/TEST/PCX.C new file mode 100644 index 0000000..1966893 --- /dev/null +++ b/TEST/PCX.C @@ -0,0 +1,37 @@ +#include "pcx.h" +#include "dgl.h" +#include +#include "helpers.h" + +void test_pcx(void) { + SURFACE *pcx; + DGL_ERROR err; + byte pcx_palette[768]; + byte original_palette[768]; + + surface_clear(screen, 0); + pal_get(original_palette); + + pcx = pcx_load("notreal.pcx", NULL); + err = dgl_last_error(); + ASSERT(pcx == NULL); + ASSERT(err != DGL_NONE); + + pcx = pcx_load("test.pcx", NULL); + ASSERT(pcx != NULL); + + surface_blit(pcx, screen, 0, 0); + getch(); + + surface_clear(screen, 0); + surface_free(pcx); + pcx = pcx_load("test.pcx", pcx_palette); + ASSERT(pcx != NULL); + + pal_set(pcx_palette); + surface_blit(pcx, screen, 0, 0); + + getch(); + pal_set(original_palette); +} + diff --git a/TEST/PCX.H b/TEST/PCX.H new file mode 100644 index 0000000..59fd7fb --- /dev/null +++ b/TEST/PCX.H @@ -0,0 +1,7 @@ +#ifndef DGL_TEST_PCX_H_INCLUDED +#define DGL_TEST_PCX_H_INCLUDED + +void test_pcx(void); + +#endif + diff --git a/TEST/PSET.C b/TEST/PSET.C new file mode 100644 index 0000000..ae55f02 --- /dev/null +++ b/TEST/PSET.C @@ -0,0 +1,114 @@ +#include "pset.h" +#include "dgl.h" +#include +#include "helpers.h" + +// pixel drawing done largely using pointers directly, with the assistance +// of helper functions to get correct initial pointer positions. +// starting at (10,10), draw 256 colour palette in a 16x16 pixel box. +// draw white "guide" lines from (0,0) to (10,10) +void test_pixels_1(void) { + byte *p; + int i, x, y; + + surface_clear(screen, 0); + + p = surface_pointer(screen, 10, 10); + ASSERT(p == (screen->pixels + (10 * screen->width) + 10)); + + i = 0; + for (y = 0; y < 16; ++y) { + for (x = 0; x < 16; ++x) { + *p = (byte)i; + ++p; + ++i; + } + p += (screen->width - 16); + } + + p = surface_pointer(screen, 0, 0); + for (i = 0; i < 10; ++i) { + *p = 15; + p += (screen->width + 1); + } + p = surface_pointer(screen, 10, 0); + for (i = 0; i < 10; ++i) { + *p = 15; + p += screen->width; + } + p = surface_pointer(screen, 0, 10); + for (i = 0; i < 10; ++i) { + *p = 15; + ++p; + } + + getch(); +} + +// pixel drawing using pset, and pixel getting using point +// draws two blue, green, cyan, red pixels each in each screen corner. +// the second pixel colour is drawn by sampling the first. +void test_pixels_2(void) { + byte c1, c2, c3, c4; + + surface_clear(screen, 0); + + surface_pset(screen, 0, 0, 1); + surface_pset(screen, 319, 0, 2); + surface_pset(screen, 0, 199, 3); + surface_pset(screen, 319, 199, 4); + + surface_pset_f(screen, 10, 0, 1); + surface_pset_f(screen, 309, 0, 2); + surface_pset_f(screen, 10, 199, 3); + surface_pset_f(screen, 309, 199, 4); + + c1 = surface_point(screen, 0, 0); + c2 = surface_point(screen, 319, 0); + c3 = surface_point(screen, 0, 199); + c4 = surface_point(screen, 319, 199); + ASSERT(c1 == 1 && c2 == 2 && c3 == 3 && c4 == 4); + + surface_pset(screen, 1, 1, c1); + surface_pset(screen, 318, 1, c2); + surface_pset(screen, 1, 198, c3); + surface_pset(screen, 318, 198, c4); + + c1 = surface_point_f(screen, 10, 0); + c2 = surface_point_f(screen, 309, 0); + c3 = surface_point_f(screen, 10, 199); + c4 = surface_point_f(screen, 309, 199); + ASSERT(c1 == 1 && c2 == 2 && c3 == 3 && c4 == 4); + + surface_pset_f(screen, 11, 1, c1); + surface_pset_f(screen, 308, 1, c2); + surface_pset_f(screen, 11, 198, c3); + surface_pset_f(screen, 308, 198, c4); + + getch(); +} + +// pixel drawing with clipping (using pset). +// draws 4 white lines 10 pixels long, going 5 pixels out of bounds off each +// edge (top, left, bottom, right) of the screen. red marker pixels are at +// the inside edge of each line to mark a known reference point +void test_pixels_clipping(void) { + int i, x, y; + + surface_clear(screen, 0); + + surface_pset(screen, 5, 100, 4); + surface_pset(screen, 314, 100, 4); + surface_pset(screen, 160, 5, 4); + surface_pset(screen, 160, 194, 4); + + for (i = 0; i < 10; ++i) { + surface_pset(screen, i - 5, 100, 15); + surface_pset(screen, 315 + i, 100, 15); + surface_pset(screen, 160, i - 5, 15); + surface_pset(screen, 160, 195 + i, 15); + } + + getch(); +} + diff --git a/TEST/PSET.H b/TEST/PSET.H new file mode 100644 index 0000000..2171e42 --- /dev/null +++ b/TEST/PSET.H @@ -0,0 +1,9 @@ +#ifndef DGL_TEST_PSET_H_INCLUDED +#define DGL_TEST_PSET_H_INCLUDED + +void test_pixels_1(void); +void test_pixels_2(void); +void test_pixels_clipping(void); + +#endif + diff --git a/TEST/RECT.C b/TEST/RECT.C new file mode 100644 index 0000000..32e4d39 --- /dev/null +++ b/TEST/RECT.C @@ -0,0 +1,208 @@ +#include "rect.h" +#include "dgl.h" +#include + +// draws two rectangles. red pixels mark the extents of the rects. a +// duplicate of the first rectangle is drawn using the "fast" variant. +void test_rect(void) { + int x1, y1, x2, y2; + + surface_clear(screen, 0); + + x1 = 10; y1 = 10; x2 = 90; y2 = 90; + surface_pset(screen, x1 - 1, y1, 4); + surface_pset(screen, x1, y1 - 1, 4); + surface_pset(screen, x2 + 1, y1, 4); + surface_pset(screen, x2, y1 - 1, 4); + surface_pset(screen, x1 - 1, y2, 4); + surface_pset(screen, x1, y2 + 1, 4); + surface_pset(screen, x2 + 1, y2, 4); + surface_pset(screen, x2, y2 + 1, 4); + surface_rect(screen, x1, y1, x2, y2, 1); + + x1 = 10; y1 = 110; x2 = 90; y2 = 190; + surface_pset(screen, x1 - 1, y1, 4); + surface_pset(screen, x1, y1 - 1, 4); + surface_pset(screen, x2 + 1, y1, 4); + surface_pset(screen, x2, y1 - 1, 4); + surface_pset(screen, x1 - 1, y2, 4); + surface_pset(screen, x1, y2 + 1, 4); + surface_pset(screen, x2 + 1, y2, 4); + surface_pset(screen, x2, y2 + 1, 4); + surface_rect_f(screen, x1, y1, x2, y2, 1); + + x1 = 190; y1 = 90; x2 = 110; y2 = 10; + surface_pset(screen, x2 - 1, y2, 4); + surface_pset(screen, x2, y2 - 1, 4); + surface_pset(screen, x1 + 1, y2, 4); + surface_pset(screen, x1, y2 - 1, 4); + surface_pset(screen, x2 - 1, y1, 4); + surface_pset(screen, x2, y1 + 1, 4); + surface_pset(screen, x1 + 1, y1, 4); + surface_pset(screen, x1, y1 + 1, 4); + surface_rect(screen, x1, y1, x2, y2, 2); + + getch(); +} + +// draws 4 rects in each of the top-left and bottom-right corners (two in each +// corner will be completely out of bounds, so should not be visible). also, +// two long rects are drawn along the center of the screen and they each +// extend beyond the edges of the screen. red pixels are drawn to mark rect +// extents. +void test_rect_clipping(void) { + int x1, y1, x2, y2; + + surface_clear(screen, 0); + + x1 = -8; y1 = 10; x2 = 7; y2 = 25; + surface_pset(screen, x2, y1 - 1, 4); + surface_pset(screen, x2 + 1, y1, 4); + surface_pset(screen, x2 + 1, y2, 4); + surface_pset(screen, x2, y2 + 1, 4); + surface_rect(screen, x1, y1, x2, y2, 1); + + surface_rect(screen, -16, 30, -1, 46, 10); + + x1 = 20; y1 = -8; x2 = 35; y2 = 7; + surface_pset(screen, x1 - 1, y2, 4); + surface_pset(screen, x1, y2 + 1, 4); + surface_pset(screen, x2 + 1, y2, 4); + surface_pset(screen, x2, y2 + 1, 4); + surface_rect(screen, x1, y1, x2, y2, 2); + + surface_rect(screen, 40, -16, 55, -1, 11); + + x1 = 313; y1 = 170; x2 = 328; y2 = 185; + surface_pset(screen, x1, y1 - 1, 4); + surface_pset(screen, x1 - 1, y1, 4); + surface_pset(screen, x1 - 1, y2, 4); + surface_pset(screen, x1, y2 + 1, 4); + surface_rect(screen, x1, y1, x2, y2, 3); + + surface_rect(screen, 320, 150, 335, 165, 12); + + x1 = 285; y1 = 193; x2 = 300; y2 = 208; + surface_pset(screen, x1 - 1, y1, 4); + surface_pset(screen, x1, y1 - 1, 4); + surface_pset(screen, x2 + 1, y1, 4); + surface_pset(screen, x2, y1 - 1, 4); + surface_rect(screen, x1, y1, x2, y2, 5); + + surface_rect(screen, 265, 200, 280, 215, 13); + + x1 = 150; y1 = -10; x2 = 170; y2 = 210; + surface_pset(screen, x1 - 1, 10, 4); + surface_pset(screen, x2 + 1, 10, 4); + surface_rect(screen, x1, y1, x2, y2, 7); + + x1 = -10; y1 = 90; x2 = 330; y2 = 110; + surface_pset(screen, 10, y1 - 1, 4); + surface_pset(screen, 10, y2 + 1, 4); + surface_rect(screen, x1, y1, x2, y2, 8); + + getch(); +} + +// draws two filled rectangles. red pixels mark the extents of the rects. a +// duplicate of the first rectangle is drawn using the "fast" variant. +void test_filled_rect(void) { + int x1, y1, x2, y2; + + surface_clear(screen, 0); + + x1 = 10; y1 = 10; x2 = 90; y2 = 90; + surface_pset(screen, x1 - 1, y1, 4); + surface_pset(screen, x1, y1 - 1, 4); + surface_pset(screen, x2 + 1, y1, 4); + surface_pset(screen, x2, y1 - 1, 4); + surface_pset(screen, x1 - 1, y2, 4); + surface_pset(screen, x1, y2 + 1, 4); + surface_pset(screen, x2 + 1, y2, 4); + surface_pset(screen, x2, y2 + 1, 4); + surface_filled_rect(screen, x1, y1, x2, y2, 1); + + x1 = 10; y1 = 110; x2 = 90; y2 = 190; + surface_pset(screen, x1 - 1, y1, 4); + surface_pset(screen, x1, y1 - 1, 4); + surface_pset(screen, x2 + 1, y1, 4); + surface_pset(screen, x2, y1 - 1, 4); + surface_pset(screen, x1 - 1, y2, 4); + surface_pset(screen, x1, y2 + 1, 4); + surface_pset(screen, x2 + 1, y2, 4); + surface_pset(screen, x2, y2 + 1, 4); + surface_filled_rect_f(screen, x1, y1, x2, y2, 1); + + x1 = 190; y1 = 90; x2 = 110; y2 = 10; + surface_pset(screen, x2 - 1, y2, 4); + surface_pset(screen, x2, y2 - 1, 4); + surface_pset(screen, x1 + 1, y2, 4); + surface_pset(screen, x1, y2 - 1, 4); + surface_pset(screen, x2 - 1, y1, 4); + surface_pset(screen, x2, y1 + 1, 4); + surface_pset(screen, x1 + 1, y1, 4); + surface_pset(screen, x1, y1 + 1, 4); + surface_filled_rect(screen, x1, y1, x2, y2, 2); + + getch(); +} + +// draws 4 rects in each of the top-left and bottom-right corners (two in each +// corner will be completely out of bounds, so should not be visible). also, +// two long rects are drawn along the center of the screen and they each +// extend beyond the edges of the screen. red pixels are drawn to mark rect +// extents. +void test_filled_rect_clipping(void) { + int x1, y1, x2, y2; + + surface_clear(screen, 0); + + x1 = -8; y1 = 10; x2 = 7; y2 = 25; + surface_pset(screen, x2, y1 - 1, 4); + surface_pset(screen, x2 + 1, y1, 4); + surface_pset(screen, x2 + 1, y2, 4); + surface_pset(screen, x2, y2 + 1, 4); + surface_filled_rect(screen, x1, y1, x2, y2, 1); + + surface_filled_rect(screen, -16, 30, -1, 46, 10); + + x1 = 20; y1 = -8; x2 = 35; y2 = 7; + surface_pset(screen, x1 - 1, y2, 4); + surface_pset(screen, x1, y2 + 1, 4); + surface_pset(screen, x2 + 1, y2, 4); + surface_pset(screen, x2, y2 + 1, 4); + surface_filled_rect(screen, x1, y1, x2, y2, 2); + + surface_filled_rect(screen, 40, -16, 55, -1, 11); + + x1 = 313; y1 = 170; x2 = 328; y2 = 185; + surface_pset(screen, x1, y1 - 1, 4); + surface_pset(screen, x1 - 1, y1, 4); + surface_pset(screen, x1 - 1, y2, 4); + surface_pset(screen, x1, y2 + 1, 4); + surface_filled_rect(screen, x1, y1, x2, y2, 3); + + surface_filled_rect(screen, 320, 150, 335, 165, 12); + + x1 = 285; y1 = 193; x2 = 300; y2 = 208; + surface_pset(screen, x1 - 1, y1, 4); + surface_pset(screen, x1, y1 - 1, 4); + surface_pset(screen, x2 + 1, y1, 4); + surface_pset(screen, x2, y1 - 1, 4); + surface_filled_rect(screen, x1, y1, x2, y2, 5); + + surface_filled_rect(screen, 265, 200, 280, 215, 13); + + x1 = 150; y1 = -10; x2 = 170; y2 = 210; + surface_pset(screen, x1 - 1, 10, 4); + surface_pset(screen, x2 + 1, 10, 4); + surface_filled_rect(screen, x1, y1, x2, y2, 7); + + x1 = -10; y1 = 90; x2 = 330; y2 = 110; + surface_pset(screen, 10, y1 - 1, 4); + surface_pset(screen, 10, y2 + 1, 4); + surface_filled_rect(screen, x1, y1, x2, y2, 8); + + getch(); +} + diff --git a/TEST/RECT.H b/TEST/RECT.H new file mode 100644 index 0000000..074470a --- /dev/null +++ b/TEST/RECT.H @@ -0,0 +1,10 @@ +#ifndef DGL_TEST_RECT_H_INCLUDED +#define DGL_TEST_RECT_H_INCLUDED + +void test_rect(void); +void test_rect_clipping(void); +void test_filled_rect(void); +void test_filled_rect_clipping(void); + +#endif + diff --git a/TEST/SURFACE.C b/TEST/SURFACE.C new file mode 100644 index 0000000..0538e09 --- /dev/null +++ b/TEST/SURFACE.C @@ -0,0 +1,21 @@ +#include "surface.h" +#include "dgl.h" +#include + +extern SURFACE *backbuffer; + +// fill screen entirely with blue +void test_surface_clear(void) { + surface_clear(screen, 1); + + getch(); +} + +// fill screen entirely with green, using the backbuffer first +void test_surface_copy(void) { + surface_clear(backbuffer, 2); + surface_copy(backbuffer, screen); + + getch(); +} + diff --git a/TEST/SURFACE.H b/TEST/SURFACE.H new file mode 100644 index 0000000..7cc2f7d --- /dev/null +++ b/TEST/SURFACE.H @@ -0,0 +1,8 @@ +#ifndef DGL_TEST_SURFACE_H_INCLUDED +#define DGL_TEST_SURFACE_H_INCLUDED + +void test_surface_clear(void); +void test_surface_copy(void); + +#endif + diff --git a/TEST/TEST.C b/TEST/TEST.C new file mode 100644 index 0000000..4b288e0 --- /dev/null +++ b/TEST/TEST.C @@ -0,0 +1,75 @@ +#include +#include +#include "dgl.h" +#include "helpers.h" + +#include "fixed.h" +#include "vector2.h" +#include "surface.h" +#include "pset.h" +#include "line.h" +#include "rect.h" +#include "blit.h" +#include "text.h" +#include "pal.h" +#include "pcx.h" + +SURFACE *backbuffer = NULL; + +void break_handler(int sig) { + exit(0); +} + +int main(void) { + signal(SIGINT, break_handler); + + dgl_init(); + + ASSERT(screen == NULL); + + if (!video_init()) { + printf("Error initializing video: %s\n", dgl_last_error_message()); + return 1; + } + + ASSERT(screen != NULL); + ASSERT(screen->width == 320 && screen->height == 200); + + backbuffer = surface_create(320, 200); + ASSERT(backbuffer != NULL); + ASSERT(backbuffer->width == 320 && backbuffer->height == 200); + + test_fixed(); + test_vector2i(); + test_vector2f(); + test_surface_clear(); + test_surface_copy(); + test_pixels_1(); + test_pixels_2(); + test_pixels_clipping(); + test_hline(); + test_hline_clipping(); + test_vline(); + test_vline_clipping(); + test_line(); + test_line_clipping(); + test_rect(); + test_rect_clipping(); + test_filled_rect(); + test_filled_rect_clipping(); + test_blit(); + test_blit_clipping(); + test_sprite(); + test_sprite_clipping(); + test_text(); + test_text_clipping(); + test_palette(); + test_palette_fading(); + test_pcx(); + + surface_free(backbuffer); + + + return 0; +} + diff --git a/TEST.PCX b/TEST/TEST.PCX similarity index 100% rename from TEST.PCX rename to TEST/TEST.PCX diff --git a/TEST/TEXT.C b/TEST/TEXT.C new file mode 100644 index 0000000..3ef9934 --- /dev/null +++ b/TEST/TEXT.C @@ -0,0 +1,95 @@ +#include "text.h" +#include "dgl.h" +#include +#include + +// prints out some simple text messages, including ones with newlines in them. +// also prints out the entire 1-127 ASCII character set in a 16x8 grid. +// a duplicate set of text is drawn using the "fast" variants. +void test_text(void) { + int i, x, y; + char string[255]; + char *p; + + surface_clear(screen, 0); + memset(string, 0, 255); + + surface_text(screen, 10, 10, 15, "Hello, world!"); + surface_text_f(screen, 170, 10, 15, "Hello, world!"); + + surface_filled_rect(screen, 8, 28, 114, 40, 7); + surface_text(screen, 10, 30, 15, "transparency!"); + surface_filled_rect_f(screen, 168, 28, 274, 40, 7); + surface_text_f(screen, 170, 30, 15, "transparency!"); + + surface_text(screen, 10, 50, 15, "line 1\nline 2"); + surface_text_f(screen, 170, 50, 15, "line 1\nline 2"); + + surface_printf(screen, 10, 70, 15, "printf pi %.5f", PI); + surface_printf_f(screen, 170, 70, 15, "printf pi %.5f", PI); + + p = &string[0]; + for (i = 1; i <= 127; ++i, ++p) { + if (i % 16 == 0) { + *p = '\n'; + ++p; + } + if (i == 10) + *p = ' '; // will be interpreted as a \n (and hence, not shown) + else + *p = (char)i; + } + + surface_text(screen, 10, 100, 15, string); + surface_text_f(screen, 170, 100, 15, string); + + getch(); +} + +// text is drawn along each edge of the screen. two messages are drawn at each +// edge, but one is completely out of bounds so the second should not be +// visible. red rects are drawn marking the extents of the text. +void test_text_clipping(void) { + int x, y; + char message[] = "Hello, world!"; + int len = strlen(message); + int width = len * 8; + int height = 8; + + surface_clear(screen, 0); + + x = -32; y = 10; + surface_rect(screen, x - 1, y - 1, x + width, y + height, 4); + surface_text(screen, x, y, 9, message); + + x = 80; y = -4; + surface_rect(screen, x - 1, y - 1, x + width, y + height, 4); + surface_text(screen, x, y, 10, message); + + x = 288; y = 120; + surface_rect(screen, x - 1, y - 1, x + width, y + height, 4); + surface_text(screen, x, y, 11, message); + + x = 200; y = 196; + surface_rect(screen, x - 1, y - 1, x + width, y + height, 4); + surface_text(screen, x, y, 12, message); + + x = -232; y = 10; + surface_rect(screen, x - 1, y - 1, x + width, y + height, 4); + surface_text(screen, x, y, 5, message); + + x = 80; y = -24; + surface_rect(screen, x - 1, y - 1, x + width, y + height, 4); + surface_text(screen, x, y, 6, message); + + x = 360; y = 120; + surface_rect(screen, x - 1, y - 1, x + width, y + height, 4); + surface_text(screen, x, y, 7, message); + + x = 200; y = 240; + surface_rect(screen, x - 1, y - 1, x + width, y + height, 4); + surface_text(screen, x, y, 8, message); + + getch(); +} + diff --git a/TEST/TEXT.H b/TEST/TEXT.H new file mode 100644 index 0000000..474440e --- /dev/null +++ b/TEST/TEXT.H @@ -0,0 +1,8 @@ +#ifndef DGL_TEST_TEXT_H_INCLUDED +#define DGL_TEST_TEXT_H_INCLUDED + +void test_text(void); +void test_text_clipping(void); + +#endif + diff --git a/TEST/VECTOR2.C b/TEST/VECTOR2.C new file mode 100644 index 0000000..032c96d --- /dev/null +++ b/TEST/VECTOR2.C @@ -0,0 +1,134 @@ +#include "vector2.h" +#include "dgl.h" +#include "helpers.h" + +void test_vector2i(void) { + VECTOR2I a, b, c; + int i; + + c = vector2i(3, 7); + ASSERT(c.x == 3 && c.y == 7); + + vector2i_set(&c, 1, 2); + ASSERT(c.x == 1 && c.y == 2); + + a = vector2i(1, 2); + b = vector2i(1, 2); + ASSERT(vector2i_equals(a, b)); + + a = vector2i(3, 4); + b = vector2i(1, 2); + + c = vector2i_add(a, b); + ASSERT(c.x == 4 && c.y == 6); + + c = vector2i_sub(a, b); + ASSERT(c.x == 2 && c.y == 2); + + c = vector2i_mul(a, b); + ASSERT(c.x == 3 && c.y == 8); + + c = vector2i_muls(a, 2); + ASSERT(c.x == 6 && c.y == 8); + + c = vector2i_div(a, b); + ASSERT(c.x == 3 && c.y == 2); + + c = vector2i_divs(a, 2); + ASSERT(c.x == 1 && c.y == 2); + + a = vector2i(1, 1); + b = vector2i(1, 3); + i = vector2i_distance(a, b); + ASSERT(i == 2); + + i = vector2i_distancesq(a, b); + ASSERT(i == 4); + + a = vector2i(-12, 16); + b = vector2i(12, 9); + i = vector2i_dot(a, b); + ASSERT(i == 0); + + a = vector2i(-3, 0); + i = vector2i_length(a); + ASSERT(i == 3); + + i = vector2i_lengthsq(a); + ASSERT(i == 9); + + a = vector2i(5, 0); + b = vector2i(10, 0); + c = vector2i_lerp(a, b, 0.5f); + ASSERT(c.x == 7 && c.y == 0); +} + +void test_vector2f(void) { + VECTOR2F a, b, c; + float f; + + c = vector2f(3.0f, 7.0f); + ASSERT(F_EQU(c.x, 3.0f) && F_EQU(c.y, 7.0f)); + + vector2f_set(&c, 1.0f, 2.0f); + ASSERT(F_EQU(c.x, 1.0f) && F_EQU(c.y, 2.0f)); + + a = vector2f(1.0f, 2.0f); + b = vector2f(1.0f, 2.0f); + ASSERT(vector2f_equals(a, b)); + + a = vector2f(3.0f, 4.0f); + b = vector2f(1.0f, 2.0f); + + c = vector2f_add(a, b); + ASSERT(F_EQU(c.x, 4.0f) && F_EQU(c.y, 6.0f)); + + c = vector2f_sub(a, b); + ASSERT(F_EQU(c.x, 2.0f) && F_EQU(c.y, 2.0f)); + + c = vector2f_mul(a, b); + ASSERT(F_EQU(c.x, 3.0f) && F_EQU(c.y, 8.0f)); + + c = vector2f_muls(a, 0.5f); + ASSERT(F_EQU(c.x, 1.5f) && F_EQU(c.y, 2.0f)); + + c = vector2f_div(a, b); + ASSERT(F_EQU(c.x, 3.0f) && F_EQU(c.y, 2.0f)); + + c = vector2f_divs(a, 0.5f); + ASSERT(F_EQU(c.x, 6.0f) && F_EQU(c.y, 8.0f)); + + a = vector2f(1.0f, 1.0f); + b = vector2f(1.0f, 3.0f); + f = vector2f_distance(a, b); + ASSERT(F_EQU(f, 2.0f)); + + f = vector2f_distancesq(a, b); + ASSERT(F_EQU(f, 4.0f)); + + a = vector2f(-12.0f, 16.0f); + b = vector2f(12.0f, 9.0f); + f = vector2f_dot(a, b); + ASSERT(F_EQU(f, 0.0f)); + + a = vector2f(-3.0f, 0.0f); + f = vector2f_length(a); + ASSERT(F_EQU(f, 3.0f)); + + f = vector2f_lengthsq(a); + ASSERT(F_EQU(f, 9.0f)); + + a = vector2f(7.0f, 7.0f); + c = vector2f_normalize(a); + ASSERT(F_EQU(c.x, 0.70710f) && F_EQU(c.y, 0.70710f)); + + a = vector2f(10.0f, 0.0f); + c = vector2f_set_length(a, 2.0f); + ASSERT(F_EQU(c.x, 2.0f) && F_EQU(c.y, 0.0f)); + + a = vector2f(5.0f, 0.0f); + b = vector2f(10.0f, 0.0f); + c = vector2f_lerp(a, b, 0.5f); + ASSERT(F_EQU(c.x, 7.5f) && F_EQU(c.y, 0.0f)); +} + diff --git a/TEST/VECTOR2.H b/TEST/VECTOR2.H new file mode 100644 index 0000000..0e3dae4 --- /dev/null +++ b/TEST/VECTOR2.H @@ -0,0 +1,8 @@ +#ifndef DGL_TEST_VECTOR2_H_INCLUDED +#define DGL_TEST_VECTOR2_H_INCLUDED + +void test_vector2i(void); +void test_vector2f(void); + +#endif +