Added wbezier.c, wspoly.c - exercised by examples/wgt33.c, fixed memory alignment issue with lib/mem.c

This commit is contained in:
Adam Greenwood-Byrne 2021-03-19 19:59:27 +00:00
parent f18ad79676
commit 239a0690e1
6 changed files with 320 additions and 2 deletions

View file

@ -0,0 +1,99 @@
#include "wgt.h"
#include "include/mem.h"
// ######## REQUIRED FUNCTIONS ########
unsigned long state0 = 1000;
unsigned long state1 = 2000;
unsigned long rand(void)
{
unsigned long s1 = state0;
unsigned long s0 = state1;
state0 = s0;
s1 ^= s1 << 23;
s1 ^= s1 >> 17;
s1 ^= s0;
s1 ^= s0 >> 26;
state1 = s1;
return state0 + state1;
}
void wait_msec(unsigned int n)
{
register unsigned long f, t, r;
// Get the current counter frequency
asm volatile ("mrs %0, cntfrq_el0" : "=r"(f));
// Read the current counter
asm volatile ("mrs %0, cntpct_el0" : "=r"(t));
// Calculate expire value for counter
t+=((f/1000)*n)/1000;
do{asm volatile ("mrs %0, cntpct_el0" : "=r"(r));}while(r<t);
}
// ######## STUB FUNCTIONS ########
unsigned int kb = 0;
unsigned int kbhit(void) {
kb++;
return kb / 500;
}
void getch(void) {
wait_msec(0x500000);
kb = 0;
}
// ######## WGT EXAMPLES ########
#define NUM_IN 5 /* number of random points */
#define NUM_OUT 30 /* number of points of bezier curve */
/* Fewer points will make more chunky line */
void wgt33()
{
tpolypoint inpoint[NUM_IN]; /* Array with the normal curve points */
tpolypoint outpoint[NUM_OUT]; /* Array with smooth curve points */
block other; /* Pointer to our second screen */
int i; /* Loop counter */
set_clock_rate(get_max_clock());
mem_init();
vga256 (); /* Initialize graphics mode */
other = wnewblock (0, 0, 319, 199); /* Allocate second screen */
wsetcolor (vgapal[15]); /* Draw with white */
do {
wsetscreen (other); /* We'll draw on the hidden screen */
wcls (vgapal[0]); /* Clear it with black */
for (i = 0; i < NUM_IN; i++) /* Randomize the BEZIER control pts */
{
inpoint[i].x = rand() % 320;
inpoint[i].y = rand() % 200;
}
wbezier (inpoint, NUM_IN, outpoint, NUM_OUT); /* Generate line */
whollowpoly (outpoint, NUM_OUT, 0, 0, OPEN_POLY);
/* draw the smooth curve */
wnormscreen (); /* Reset drawing to visual screen */
wputblock (0, 0, other, 0); /* Show the screen */
getch();
} while (1);
wfreeblock (other); /* Free our screen buffer */
}
void main()
{
wgt33();
while (1);
}

View file

@ -16,8 +16,8 @@ void mem_init()
{
// Align the start of heap to an 8-byte boundary
if ((long)&HEAP_START % 8 != 0) {
HEAP_START += 8 - ((long)&HEAP_START % 8);
if ((long)HEAP_START % 8 != 0) {
HEAP_START += 8 - ((long)HEAP_START % 8);
}
HEAP_END = (unsigned char *)(HEAP_START + HEAP_SIZE);
@ -28,6 +28,9 @@ void *malloc(unsigned int size)
{
if (size > 0) {
void *allocated = freeptr;
if ((long)allocated % 8 != 0) {
allocated += 8 - ((long)allocated % 8);
}
if ((unsigned char *)(allocated + size) > HEAP_END) {
return 0;

59
part12-wgt/wbezier.c Normal file
View file

@ -0,0 +1,59 @@
#include "wgt.h"
#include "include/mem.h"
void wbezier (tpolypoint *rawpts, short numraw, tpolypoint *curvepts, short numcurve)
/* Bezier curve algorithm submitted to us by Claude Morais */
{
double *combi;
double deltat, temp;
double prod,quot;
double sumx,sumy;
short tmp, count;
combi = malloc (sizeof(double)*numraw);
numraw--;
deltat = 1.0 / (numcurve - 1);
combi[0] = combi[numraw] = 1.0;
for (tmp = 0; tmp <= (numraw - 2); tmp++)
combi[tmp + 1] = (combi[tmp] * (numraw - tmp)) / (tmp + 1);
for (count = 0; count < numcurve; count++)
{
if ((temp = count*deltat) <= 0.5)
{
quot = prod = 1.0 - temp;
for (tmp = 1; tmp < numraw; tmp++)
prod *= quot;
quot = temp / quot;
sumx = rawpts[numraw].x;
sumy = rawpts[numraw].y;
for (tmp = numraw - 1; tmp >= 0; tmp--)
{
sumx = combi[tmp]* rawpts[tmp].x + quot* sumx;
sumy = combi[tmp]* rawpts[tmp].y + quot* sumy;
}
}
else
{
quot = prod = temp;
for (tmp = 1; tmp < numraw; tmp++)
prod *= quot;
quot = (1.0 - temp) / quot;
sumx = rawpts[0].x;
sumy = rawpts[0].y;
for (tmp = 1; tmp <= numraw; tmp++)
{
sumx = combi[tmp]* rawpts[tmp].x + quot* sumx;
sumy = combi[tmp]* rawpts[tmp].y + quot* sumy;
}
}
curvepts[count].x = (sumx*prod);
curvepts[count].y = (sumy*prod);
}
free (combi);
}

View file

@ -51,6 +51,19 @@ extern unsigned int currentcolor;
/* Clipping boundaries */
extern short bx,by,tx,ty;
/* Polygon point definition */
typedef struct
{
short x,y; /* Coordinate on the screen */
short sx,sy; /* Coordinate on the texture if texture is used,
otherwise sx = color point */
/* sx is used for Gouraud shading as well (color of the point) */
} tpolypoint;
/* whollowpoly types */
#define CLOSED_POLY 0
#define OPEN_POLY 1
// ######## HELPER FUNCTIONS ########
void *memset(void *dest, unsigned int val, unsigned len);
@ -126,3 +139,6 @@ void wcopyscreen (short x, short y, short x2, short y2, block source, short dest
void wsline (short x, short y, short x2, short y2, short *y_array);
void wwarp (short sx, short ex, short *tpy, short *bty, block ptr, short mode);
void wresize_column (short x, short y, short y2, block image, short column, short mode);
void wsolidpoly (tpolypoint *vertexlist, short numvertex, short x, short y, void (*customline)(short, short, short));
void whollowpoly(tpolypoint *vertexlist, short numvertex, short x, short y, short closemode);
void wbezier (tpolypoint *rawpts, short numraw, tpolypoint *curvepts, short numcurve);

41
part12-wgt/winitply.c Normal file
View file

@ -0,0 +1,41 @@
#include "wgt.h"
#include "include/mem.h"
short *pinit_array;
short *pstartx;
short *pendx;
short *pinten1;
short *pinten2;
short *polyx2;
short *polyy2;
short polygon_buffer_size;
void winitpoly (short maxrows)
{
int bytes;
int ctr;
polygon_buffer_size = maxrows;
bytes = 2 * maxrows;
pstartx = malloc (bytes);
pendx = malloc (bytes);
pinten1 = malloc (bytes);
pinten2 = malloc (bytes);
polyx2 = malloc (bytes);
polyy2 = malloc (bytes);
pinit_array = malloc (bytes);
for (ctr = 0; ctr < maxrows; ctr++)
pinit_array[ctr] = -16000;
}
void wdeinitpoly (void)
{
free (pstartx);
free (pendx);
free (pinten1);
free (pinten2);
free (polyx2);
free (polyy2);
free (pinit_array);
}

100
part12-wgt/wspoly.c Normal file
View file

@ -0,0 +1,100 @@
#include "wgt.h"
extern short *pinit_array;
extern short *pstartx;
extern short *pendx;
extern short polygon_buffer_size;
static void wspolyline (short x1, short y1, short x2, short y2)
{
short tmx, tmy, y;
long x, m;
if (y2 != y1)
{
if (y2 < y1)
{
tmy = y1;
y1 = y2;
y2 = tmy;
tmx = x1;
x1 = x2;
x2 = tmx;
}
x = (long)x1 << 8;
m = ((long)(x2 - x1) << 8) / ((long)(y2 - y1));
x++;
y1++;
for (y = y1; y <= y2; y++)
{
if ((y >= 0) && (y < WGT_SYS.yres)) {
if (pstartx[y] == -16000) {
pstartx[y] = x >> 8;
} else {
pendx[y] = x >> 8;
}
}
x += m;
}
}
}
void wsolidpoly (tpolypoint *vertexlist, short numvertex, short x, short y, void (*customline)(short, short, short))
{
short i;
tpolypoint *curpt, *nextpt;
if (customline == NULL)
customline = whline;
curpt = vertexlist;
nextpt = vertexlist + 1;
memcpy (pstartx, pinit_array, polygon_buffer_size << 1);
memcpy (pendx, pinit_array, polygon_buffer_size << 1);
for (i = 0; i < numvertex - 1; i++)
{
wspolyline (curpt->x + x, curpt->y + y, nextpt->x + x, nextpt->y + y);
curpt++;
nextpt++;
}
nextpt = vertexlist;
wspolyline (curpt->x + x, curpt->y + y, nextpt->x + x, nextpt->y + y);
for (i = 0; i < WGT_SYS.yres; i++)
{
if (pstartx[i] != -16000)
{
if (pendx[i] == -16000)
pendx[i] = pstartx[i];
(*customline)(pstartx[i], pendx[i], i);
}
}
}
void whollowpoly(tpolypoint *vertexlist, short numvertex, short x, short y, short closemode)
{
short i;
tpolypoint *curpt, *nextpt;
curpt = vertexlist;
nextpt = vertexlist + 1;
for (i = 0; i < numvertex - 1; i++)
{
wline (curpt->x + x, curpt->y + y, nextpt->x + x, nextpt->y + y);
curpt++;
nextpt++;
}
if (closemode == CLOSED_POLY)
{
nextpt = vertexlist;
wline (curpt->x + x, curpt->y + y, nextpt->x + x, nextpt->y + y);
}
}