Created
June 8, 2019 21:01
-
-
Save dwilliamson/ff5e59194f3986cd35b78eb1463e082a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// polygen.cpp : Defines the entry point for the console application. | |
// | |
#include "stdafx.h" | |
#include <stdio.h> | |
#include <string.h> | |
#include <conio.h> | |
#define CHAR_VALUE(c, x, y) (c[y] & (1 << (7 - x))) | |
#define CHAR_ASSIGN(c, x, y) (c[y] |= (1 << (7 - x))) | |
#define CLEAR_SCREEN { memset(tbuf, 0, 25 * 80 * 2); } | |
#define PUT_CHAR(x, y, c) (tbuf[(y * 160) + (x * 2)] = c) | |
typedef unsigned char byte; | |
typedef unsigned short word; | |
typedef unsigned long dword; | |
#pragma pack(push,1 ) | |
typedef struct | |
{ | |
unsigned char x, y; | |
} Point2D; | |
typedef struct | |
{ | |
Point2D pt[3]; | |
} Triangle; | |
#pragma pack(pop) | |
typedef struct | |
{ | |
byte pos_x, pos_y; | |
byte width, height; | |
} Box; | |
typedef struct | |
{ | |
byte bitmap[8]; /* Image from ROM */ | |
byte mask[8]; /* Which areas have been mapped */ | |
Box box_list[40]; /* List of boxes */ | |
dword box_ctr; /* Current number of boxes */ | |
Triangle tri_list[40 * 3]; /* Glide type triangle list */ | |
} CharModel; | |
byte *fbuf = (byte *)0xFFA6EL; | |
byte *tbuf = (byte *)0xB8000L; | |
void GetCharPattern(CharModel *cptr, byte value) | |
{ | |
dword offset; | |
offset = (dword)value << 3; | |
memcpy(&cptr->bitmap[0], &fbuf[offset], 8); | |
} | |
void PrintCharInText(CharModel *cptr) | |
{ | |
dword x, y; | |
printf("\n"); | |
for (y = 0; y < 8; y++) | |
{ | |
for (x = 0; x < 8; x++) | |
{ | |
if (CHAR_VALUE(cptr->bitmap, x, y)) | |
printf("*"); | |
else | |
printf(" "); | |
} | |
printf(" "); | |
for (x = 0; x < 8; x++) | |
{ | |
if (CHAR_VALUE(cptr->mask, x, y)) | |
printf("*"); | |
else | |
printf(" "); | |
} | |
printf("\n"); | |
} | |
} | |
void AddBox(CharModel *cptr, Box *bptr) | |
{ | |
memcpy(&cptr->box_list[cptr->box_ctr++], bptr, sizeof(Box)); | |
} | |
void DrawBox(Box *bptr) | |
{ | |
byte x, y; | |
for (y = 0; y < bptr->height; y++) | |
for (x = 0; x < bptr->width; x++) | |
PUT_CHAR((bptr->pos_x + x), (bptr->pos_y + y), '*'); | |
} | |
void EvaluateBoxes(CharModel *cptr) | |
{ | |
Box tbox; | |
dword x, y; | |
memset(&cptr->mask[0], 0, 8); | |
for (y = 0; y < 8; y++) | |
{ | |
memset(&tbox, 0, sizeof(Box)); | |
for (x = 0; x < 8; x++) | |
{ | |
if (CHAR_VALUE(cptr->bitmap, x, y) && !CHAR_VALUE(cptr->mask, x, y)) | |
{ | |
tbox.pos_x = (byte)x; | |
tbox.pos_y = (byte)y; | |
tbox.width = 0; | |
tbox.height = 0; | |
/* Scan across the grid */ | |
while (CHAR_VALUE(cptr->bitmap, (x + tbox.width), y) && | |
!CHAR_VALUE(cptr->mask, (x + tbox.width), y)) | |
{ | |
if ((x + tbox.width) >= 7) | |
break; | |
tbox.width++; | |
} | |
/* If the width is substantial then this must definitely be | |
* a polygon so mask the area out and continue scanning down the grid | |
* to see if the box can be expanded further. | |
*/ | |
if (tbox.width > 1) | |
{ | |
dword tx; | |
byte flag = 1; | |
for (tx = x; tx < x + tbox.width; tx++) | |
CHAR_ASSIGN(cptr->mask, tx, y); | |
/* Do a sweep-scan down the grid for any rectangles */ | |
while (flag) | |
{ | |
tbox.height++; | |
/* Can't go any further than the bottom of the grid */ | |
if ((y + tbox.height) >= 7) break; | |
/* Try not to intrude on already formed rectangles */ | |
if (x > 0 && CHAR_VALUE(cptr->bitmap, (x - 1), (y + tbox.height))) | |
break; | |
/* Try not to intrude on already formed rectangles */ | |
if ((x + tbox.width) < 7 && CHAR_VALUE(cptr->bitmap, (x + tbox.width + 1), (y + tbox.height))) | |
break; | |
/* Scan along the grid checking for any mis-matches */ | |
for (tx = x; tx < x + tbox.width; tx++) | |
{ | |
if (!CHAR_VALUE(cptr->bitmap, tx, (y + tbox.height)) || | |
CHAR_VALUE(cptr->mask, tx, (y + tbox.height))) | |
{ | |
flag = 0; | |
break; | |
} | |
} | |
/* Now fill in the mask for this row */ | |
if (flag) | |
for (tx = x; tx < x + tbox.width; tx++) | |
CHAR_ASSIGN(cptr->mask, tx, (y + tbox.height)); | |
} | |
AddBox(cptr, &tbox); | |
} | |
else | |
{ | |
/* Do a singular scan down the grid for vertical lines */ | |
while (CHAR_VALUE(cptr->bitmap, x, (y + tbox.height)) && | |
!CHAR_VALUE(cptr->mask, x, (y + tbox.height))) | |
{ | |
CHAR_ASSIGN(cptr->mask, x, (y + tbox.height)); | |
tbox.height++; | |
/* Don't over-run the grid */ | |
if ((y + tbox.height) == 7) | |
break; | |
} | |
/* This a simple vertical line so just add it straight away - it could | |
* even be a cell on it's own. | |
*/ | |
AddBox(cptr, &tbox); | |
} | |
} | |
} | |
} | |
} | |
void Generate3DModel(CharModel *cptr) | |
{ | |
dword x; | |
Box *current_box; | |
Triangle *current_tri; | |
for (x = 0; x < cptr->box_ctr; x++) | |
{ | |
current_box = &cptr->box_list[x]; | |
current_tri = &cptr->tri_list[(x << 1) + 0]; | |
current_tri->pt[0].x = current_box->pos_x; | |
current_tri->pt[0].y = current_box->pos_y; | |
current_tri->pt[1].x = current_box->pos_x + current_box->width; | |
current_tri->pt[1].y = current_box->pos_y; | |
current_tri->pt[2].x = current_box->pos_x + current_box->width; | |
current_tri->pt[2].y = current_box->pos_y + current_box->height; | |
current_tri = &cptr->tri_list[(x << 1) + 1]; | |
current_tri->pt[0].x = current_box->pos_x; | |
current_tri->pt[0].y = current_box->pos_y; | |
current_tri->pt[1].x = current_box->pos_x + current_box->width; | |
current_tri->pt[1].y = current_box->pos_y + current_box->height; | |
current_tri->pt[2].x = current_box->pos_x; | |
current_tri->pt[2].y = current_box->pos_y + current_box->height; | |
} | |
} | |
void GenerateFontFile(byte *filename, byte low_range, byte high_range) | |
{ | |
CharModel current_char; | |
byte x, triangles, y; | |
FILE *fp; | |
fp = fopen((const char *)filename, "wb"); | |
fwrite(&low_range, 1, sizeof(byte), fp); | |
fwrite(&high_range, 1, sizeof(byte), fp); | |
for (x = low_range; x < high_range; x++) | |
{ | |
memset(¤t_char, 0, sizeof(CharModel)); | |
GetCharPattern(¤t_char, x); | |
EvaluateBoxes(¤t_char); | |
PrintCharInText(¤t_char); | |
Generate3DModel(¤t_char); | |
triangles = (byte)(current_char.box_ctr * 2); | |
fwrite(&triangles, 1, sizeof(byte), fp); | |
for (y = 0; y < triangles; y++) | |
{ | |
fputc(current_char.tri_list[y].pt[0].x, fp); | |
fputc(current_char.tri_list[y].pt[0].y, fp); | |
fputc(current_char.tri_list[y].pt[1].x, fp); | |
fputc(current_char.tri_list[y].pt[1].y, fp); | |
fputc(current_char.tri_list[y].pt[2].x, fp); | |
fputc(current_char.tri_list[y].pt[2].y, fp); | |
} | |
} | |
fclose(fp); | |
} | |
int main(int argc, char* argv[]) | |
{ | |
GenerateFontFile((byte *)"c:\\lucky.fnt", 0, 128); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment