1
0

Implement FONTDEF (1)(2)

This commit is contained in:
otya128
2016-12-30 16:42:30 +09:00
parent b503d8d48b
commit 20b00236a2
2 changed files with 164 additions and 3 deletions

View File

@@ -3245,6 +3245,123 @@ class BuiltinFunction
{ {
return p.program.name(slot); return p.program.name(slot);
} }
static auto split2(R)(R range, size_t size)
{
return Split2!R(range, size);
}
unittest
{
struct IR
{
void popFront()
{
}
bool empty()
{
return true;
}
int front()
{
return 1;
}
}
static assert(isInputRange!(Split2!IR));
static assert(isInputRange!(Split2!(int[])));
}
struct Split2(R)
if (isInputRange!R)
{
R range;
size_t size;
ElementType!(R)[] item;
bool isEmpty;
this(R range, size_t size)
{
this.range = range;
this.size = size;
popFront();
}
void popFront()
{
isEmpty = range.empty;
if (isEmpty)
return;
static if (hasSlicing!R && is(range[0..size] == item))
{
item = range[0..size];
popFrontN(item, size);
}
else
{
item = new ElementType!(R)[size];
for (size_t i = 0; i < size; i++)
{
item[i] = range.front();
range.popFront();
}
}
}
auto front()
{
return item;
}
bool empty()
{
return isEmpty;
}
}
static void FONTDEF(PetitComputer p, int icode, Value array)
{
if (icode < 0 || icode > 0xFFFF)
{
throw new OutOfRange("FONTDEF", 1);
}
ushort code = cast(ushort)icode;
if (!p.console.canDefine(code))
{
throw new IllegalFunctionCall("FONTDEF"/*, 1*/);
}
int color = 4;
if (array.isString)
{
wstring definition = array.castDString;
//FONTDEF 0,"0000"*65'=>OK
if (definition.length < p.console.fontDefWidth * p.console.fontDefHeight * color)
{
throw new IllegalFunctionCall("FONTDEF", 2);
}
int[] font = new int[p.console.fontDefWidth * p.console.fontDefHeight * color];
try
{
p.console.define(code, split2(definition, 4).map!(x => x.to!int(16)).array);
}
catch (ConvException)
{
throw new IllegalFunctionCall("FONTDEF", 2);
}
return;
}
//DIM A$[63]
//FONTDEF 0,A$'=>Subscript out of range(FONTDEF:2)
//DIM A$[64]
//FONTDEF 0,A$'=>Type mismatch(FONTDEF:2)
//FONTDEF 0,1'=>Type mismatch(FONTDEF:2)
if (!array.isArray)
throw new TypeMismatch("FONTDEF", 2);
if (array.length < p.console.fontDefWidth * p.console.fontDefHeight)
throw new SubscriptOutOfRange("FONTDEF", 2);
if (!array.isNumberArray)
throw new TypeMismatch("FONTDEF", 2);
if (array.type == ValueType.IntegerArray)
{
p.console.define(code, array.integerArray.array);
}
else if (array.type == ValueType.DoubleArray)
{
p.console.define(code, array.doubleArray.array);
}
}
//alias void function(PetitComputer, Value[], Value[]) BuiltinFunc; //alias void function(PetitComputer, Value[], Value[]) BuiltinFunc;
static BuiltinFunctions[wstring] builtinFunctions; static BuiltinFunctions[wstring] builtinFunctions;
static wstring getBasicName(BFD)(const wstring def) static wstring getBasicName(BFD)(const wstring def)

View File

@@ -30,9 +30,24 @@ enum ConsoleAttribute
TREVV = 8, TREVV = 8,
} }
struct FontRect
{
int x, y, w, h;
bool define = true;
}
class Console class Console
{ {
//width 16,16 => return 16
int fontDefWidth()
{
return 8;
}
int fontDefHeight()
{
return 8;
}
int[2] fontWidths; int[2] fontWidths;
int[2] fontHeights; int[2] fontHeights;
int consoleWidthDisplay1; int consoleWidthDisplay1;
@@ -125,7 +140,7 @@ class Console
bool showCursor; bool showCursor;
bool animationCursor; bool animationCursor;
SDL_Rect[] fontTable = new SDL_Rect[65536]; FontRect[] fontTable = new FontRect[65536];
GraphicPage GRPF; GraphicPage GRPF;
PetitComputer petitcom; PetitComputer petitcom;
bool[2] visibles = [true, true]; bool[2] visibles = [true, true];
@@ -202,7 +217,7 @@ class Console
void createFontTable() void createFontTable()
{ {
auto file = File(petitcom.fontTableFile, "w"); auto file = File(petitcom.fontTableFile, "w");
std.algorithm.fill(fontTable, SDL_Rect(488,120, 8, 8));//TODO:480,120とどっちが使われているかは要調査 std.algorithm.fill(fontTable, FontRect(488,120, 8, 8, false));//TODO:480,120とどっちが使われているかは要調査
for (int i = 1; i <= 16; i++) for (int i = 1; i <= 16; i++)
{ {
string html = cast(string)get("http://smilebasic.com/supplements/unicode" ~ format("%02d",i)); string html = cast(string)get("http://smilebasic.com/supplements/unicode" ~ format("%02d",i));
@@ -229,6 +244,7 @@ class Console
file.write(fontTable[index].y, '\n'); file.write(fontTable[index].y, '\n');
fontTable[index].w = 8; fontTable[index].w = 8;
fontTable[index].h = 8; fontTable[index].h = 8;
fontTable[index].define = true;
} }
} }
} }
@@ -236,7 +252,7 @@ class Console
{ {
import std.csv; import std.csv;
import std.typecons; import std.typecons;
std.algorithm.fill(fontTable, SDL_Rect(488,120, 8, 8));//TODO:480,120とどっちが使われているかは要調査 std.algorithm.fill(fontTable, FontRect(488,120, 8, 8, false));//TODO:480,120とどっちが使われているかは要調査
auto csv = csvReader!(Tuple!(int,int,int))(readText(petitcom.fontTableFile)); auto csv = csvReader!(Tuple!(int,int,int))(readText(petitcom.fontTableFile));
foreach(record; csv) foreach(record; csv)
{ {
@@ -244,6 +260,7 @@ class Console
fontTable[record[0]].y = record[2]; fontTable[record[0]].y = record[2];
fontTable[record[0]].w = 8; fontTable[record[0]].w = 8;
fontTable[record[0]].h = 8; fontTable[record[0]].h = 8;
fontTable[record[0]].define = true;
} }
} }
void cls() void cls()
@@ -480,4 +497,31 @@ class Console
consoleC[consoleHeightC - 1] = tmp; consoleC[consoleHeightC - 1] = tmp;
tmp[] = ConsoleCharacter(0, foreColor, backColor, attr, CSRZ); tmp[] = ConsoleCharacter(0, foreColor, backColor, attr, CSRZ);
} }
bool canDefine(ushort a)
{
return fontTable[a].define;
}
void define(T)(ushort code, T[] array)
{
import otya.smilebasic.graphic;
if (!canDefine(code))
{
return;
}
auto buffer = cast(int*)GRPF.surface.pixels;
auto w = GRPF.surface.w;
auto h = GRPF.surface.h;
auto font = fontTable[code];
for (int y = 0; y < font.h; y++)
{
for (int x = 0; x < font.w; x++)
{
buffer[x + font.x + (font.y + y) * w] = Graphic.RGBA16ToARGB32Color(cast(int)array[x + y * font.w]);
}
}
//update texture
glBindTexture(GL_TEXTURE_2D, GRPF.glTexture);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_BGRA, GL_UNSIGNED_BYTE, buffer);
glFlush();
}
} }