1
0
Files
otyaSMILEBASIC/SMILEBASIC/petitcomputer.d

761 lines
25 KiB
D
Raw Normal View History

module otya.smilebasic.petitcomputer;
import derelict.sdl2.sdl;
2015-07-07 22:21:01 +09:00
import derelict.sdl2.image;
2015-08-18 17:45:21 +09:00
import derelict.opengl3.gl;
2015-07-07 22:21:01 +09:00
import std.net.curl;
import std.file;
import std.stdio;
import std.conv;
import std.string;
import std.c.stdio;
import core.sync.mutex;
import otya.smilebasic.parser;
2015-07-07 22:21:01 +09:00
class GraphicPage
{
SDL_Surface* surface;
SDL_Texture* texture;
this(SDL_Surface* s)
{
surface = s;
}
2015-08-18 17:45:21 +09:00
GLuint glTexture;
2015-07-07 22:21:01 +09:00
void createTexture(SDL_Renderer* renderer)
{
texture = SDL_CreateTextureFromSurface(renderer, surface);
2015-08-18 17:45:21 +09:00
ubyte r,g,b,a;
SDL_GetRGBA(*cast(uint*)surface.pixels, surface.format, &r, &g, &b, &a);
GLenum texture_format;
GLint nOfColors;
nOfColors = surface.format.BytesPerPixel;
if (nOfColors == 4) // contains an alpha channel
{
if (surface.format.Rmask == 0x000000ff)
texture_format = GL_RGBA;
else
texture_format = GL_BGRA;
} else if (nOfColors == 3) // no alpha channel
{
if (surface.format.Rmask == 0x000000ff)
texture_format = GL_RGB;
else
texture_format = GL_BGR;
} else {
//printf("warning: the image is not truecolor.. this will probably break\n");
// this error should not go unhandled
}
// Have OpenGL generate a texture object handle for us
glGenTextures( 1, &glTexture );
// Bind the texture object
glBindTexture( GL_TEXTURE_2D, glTexture );
// Set the texture's stretching properties
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
// Edit the texture object's image data using the information SDL_Surface gives us
glTexImage2D( GL_TEXTURE_2D, 0, nOfColors, surface.w, surface.h, 0,
texture_format, GL_UNSIGNED_BYTE, surface.pixels );
2015-07-07 22:21:01 +09:00
}
}
class PetitComputer
{
this()
2015-07-06 23:09:15 +09:00
{
new Test();
2015-07-06 23:09:15 +09:00
}
2015-07-07 22:21:01 +09:00
static const string resourceDirName = "resources";
static const string resourcePath = "./resources";
static const string fontFile = resourcePath ~ "/font.png";
static const string spriteFile = resourcePath ~ "/defsp.png";
static const string BGFile = resourcePath ~ "/defbg.png";
static const string fontTableFile = resourcePath ~ "/fonttable.txt";
int screenWidth;
int screenHeight;
int fontWidth;
int fontHeight;
int consoleWidth;
int consoleHeight;
2015-07-11 22:21:48 +09:00
int[] consoleColor =
[
0x00000000,
0xFF000000,
0xFF7F0000,
0xFFFF0000,
0xFF007F00,
0xFF00FF00,
0xFF7F7F00,
0xFFFFFF00,
0xFF00007F,
0xFF0000FF,
0xFF7F007F,
0xFFFF00FF,
0xFF007F7F,
0xFF00FFFF,
0xFF7F7F7F,
0xFFFFFFFF,
];
struct ConsoleCharacter
{
wchar charater;
int foreColor;
int backColor;
byte attr;
2015-07-11 22:21:48 +09:00
}
SDL_Color PetitColor(byte r, byte g, byte b, byte a)
{
return SDL_Color(r >> 5 << 5, g >> 5 << 5, b >> 5 << 5, a == 255 ? 255 : 0);
}
ConsoleCharacter[][] console;
2015-07-07 22:21:01 +09:00
GraphicPage[] grp;
GraphicPage GRPF;
GraphicPage[] GRPFColor;
GraphicPage[][] GRPFColorFore;
SDL_Surface* s8x8;
SDL_Texture* t8x8;
2015-08-18 17:45:21 +09:00
SDL_Surface* createSurfaceFromFile(string file)
{
SDL_RWops* stream = SDL_RWFromFile(toStringz(file), toStringz("rb"));
auto surfacesrc = IMG_LoadPNG_RW(stream);
SDL_RWclose(stream);
return surfacesrc;
}
2015-07-07 22:21:01 +09:00
//PNG画像から透過色のpixelを指定して透過しGRPを作る
GraphicPage createGraphicPage(string file, int pixel)
{
SDL_RWops* stream = SDL_RWFromFile(toStringz(file), toStringz("rb"));
auto surfacesrc = IMG_LoadPNG_RW(stream);
SDL_Surface* surface = SDL_CreateRGBSurface(0, surfacesrc.w, surfacesrc.h, 32, 0, 0, 0, 0);
SDL_Rect rect;
rect.x = 0;
rect.y = 0;
rect.w = surfacesrc.w;
rect.h = surfacesrc.h;
2015-08-18 17:45:21 +09:00
SDL_SetColorKey(surfacesrc, SDL_TRUE, (cast(uint*)surface.pixels)[pixel]);
2015-07-07 22:21:01 +09:00
int i = SDL_BlitSurface(surfacesrc, &rect, surface, &rect);
auto grp = new GraphicPage(surface);
SDL_FreeSurface(surfacesrc);
SDL_RWclose(stream);
return grp;
}
2015-08-18 17:45:21 +09:00
GraphicPage createGRPF(string file)
{
SDL_RWops* stream = SDL_RWFromFile(toStringz(file), toStringz("rb"));
auto src = IMG_LoadPNG_RW(stream);
SDL_Surface* surface = SDL_CreateRGBSurface(0, src.w, src.h, 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0xFF);
SDL_Rect rect;
rect.x = 0;
rect.y = 0;
rect.w = src.w;
rect.h = src.h;
// SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND);
// SDL_SetSurfaceBlendMode(src, SDL_BLENDMODE_BLEND);
SDL_SetColorKey(src, SDL_TRUE, (cast(uint*)src.pixels)[0]);
SDL_SetColorKey(surface, SDL_TRUE, (cast(uint*)src.pixels)[0]);
int i = SDL_BlitSurface(src, &rect, surface, &rect);
auto srcpixels = (cast(uint*)src.pixels);
auto pixels = (cast(uint*)surface.pixels);
auto aaa = surface.format.Amask;
//surface.format.Amask = 0xFF;
/+for(int x = 0; x < src.w; x++)
{
for(int y = 0; y < src.h; y++)
{
ubyte r, g, b, a;
write(x,y, ',');
SDL_GetRGBA(*pixels, surface.format, &r, &g, &b, &a);
if(r == 158 && g == 0 && b == 93)
{
r = 0;
g = 0;
b = 0;
a = 0;
*pixels = 0;
*pixels = SDL_MapRGBA(surface.format, r, g, b, a);
}/+
else
*pixels = SDL_MapRGBA(surface.format, r, g, b, a);
+/ubyte _r, _g, _b, _a;
SDL_GetRGBA(*pixels, surface.format, &_r, &_g, &_b, &_a);
pixels++;
}
}+/
SDL_RWclose(stream);
SDL_FreeSurface(src);
return new GraphicPage(surface);
}
GraphicPage createGRPF(int color, SDL_Surface *src)
{
SDL_Surface* surface = SDL_CreateRGBSurface(0, src.w, src.h, 32, 0, 0, 0, 0);
auto srcpixels = (cast(uint*)src.pixels);
auto pixels = (cast(uint*)surface.pixels);
for(int x = 0; x < src.w; x++)
{
for(int y = 0; y < src.h; y++)
{
ubyte r, g, b, a;
SDL_GetRGBA(*srcpixels, src.format, &r, &g, &b, &a);
//if(a == 0)
{
auto back = consoleColor[color];
r = back >> 16 & 0xFF;
g = back >> 8 & 0xFF;
b = back & 0xFF;
a = back >> 24 & 0xFF;
}
*pixels = SDL_MapRGBA(surface.format, r, g, b, a);
pixels++;
srcpixels++;
}
}
return new GraphicPage(surface);
}
GraphicPage createGRPF(int color, int colorFore, SDL_Surface *src)
{
SDL_Surface* surface = SDL_CreateRGBSurface(0, src.w, src.h, 32, 0, 0, 0, 0);
auto srcpixels = (cast(uint*)src.pixels);
auto pixels = (cast(uint*)surface.pixels);
for(int x = 0; x < src.w; x++)
{
for(int y = 0; y < src.h; y++)
{
ubyte r, g, b, a;
SDL_GetRGBA(*srcpixels, src.format, &r, &g, &b, &a);
if(r == 158 && g == 0 && b == 93 && a == 255)
{
auto back = consoleColor[color];
r = back >> 16 & 0xFF;
g = back >> 8 & 0xFF;
b = back & 0xFF;
a = back >> 24 & 0xFF;
}
else
{
//雑
auto fore = consoleColor[colorFore];
r = fore >> 16 & 0xFF;
g = fore >> 8 & 0xFF;
b = fore & 0xFF;
a = fore >> 24 & 0xFF;
}
*pixels = SDL_MapRGBA(surface.format, r, g, b, a);
pixels++;
srcpixels++;
}
}
return new GraphicPage(surface);
}
2015-07-07 22:21:01 +09:00
struct Point
{
int x, y;
this(int x, int y)
{
this.x = x;
this.y = y;
}
}
SDL_Rect[] fontTable = new SDL_Rect[65536];
void createFontTable()
{
string html = cast(string)get("http://smileboom.com/special/ptcm3/download/unicode/");
int pos = 0, index;
auto file = File(fontTableFile, "w");
std.algorithm.fill(fontTable, SDL_Rect(488,120, 8, 8));//TODO:480,120とどっちが使われているかは要調査
while(true)
{
pos = html.indexOf("<tr><th>U+");
if(pos == -1) break;
pos += "<tr><th>U+".length;
html = html[pos..$];
writeln(index = html.parse!int(16));
file.write(index, ',');
pos = html.indexOf("</td><td>(");
if(pos == -1) break;
pos += "</td><td>(".length;
html = html[pos..$];
writeln(fontTable[index].x = html.parse!int);
file.write(fontTable[index].x, ',');
pos = html.indexOf(',');
html = html[pos + 1..$];
munch(html, " ");
writeln(fontTable[index].y = html.parse!int);
file.write(fontTable[index].y, '\n');
fontTable[index].w = 8;
fontTable[index].h = 8;
}
}
void loadFontTable()
{
import std.csv;
import std.typecons;
std.algorithm.fill(fontTable, SDL_Rect(488,120, 8, 8));//TODO:480,120とどっちが使われているかは要調査
auto csv = csvReader!(Tuple!(int,int,int))(readText(fontTableFile));
foreach(record; csv)
{
fontTable[record[0]].x = record[1];
fontTable[record[0]].y = record[2];
fontTable[record[0]].w = 8;
fontTable[record[0]].h = 8;
}
}
void init()
{
DerelictSDL2.load();
2015-07-07 22:21:01 +09:00
DerelictSDL2Image.load();
2015-08-18 17:45:21 +09:00
DerelictGL.load();
2015-07-07 22:21:01 +09:00
if(!exists(resourcePath))
{
writeln("create ./resources");
mkdir(resourceDirName);
}
if(!exists(fontFile))
{
writeln("download font");
download("http://smileboom.com/special/ptcm3/download/unicode/image/res_font_table-320.png",
fontFile);
}
2015-08-18 17:45:21 +09:00
GRPF = createGRPF(fontFile);//createGraphicPage(fontFile, 0);
s8x8 = SDL_CreateRGBSurface(0, 8, 8, 32, 0, 0, 0, 0);
auto pixels = (cast(uint*)s8x8.pixels);
for(int x = 0; x < 8; x++)
{
for(int y = 0; y < 8; y++)
{
*pixels = SDL_MapRGBA(s8x8.format, 255, 255, 255, 255);
pixels++;
}
}
//GRPFColor = new GraphicPage[consoleColor.length];
//GRPFColorFore = new GraphicPage[][consoleColor.length];
//for(int i = 0; i < GRPFColor.length; i++)
//{
// GRPFColor[i] = createGRPF(i, GRPF.surface);
//}
/+for(int i = 0; i < GRPFColor.length; i++)
{
GRPFColorFore[i] = new GraphicPage[consoleColor.length];
for(int j = 0; j < GRPFColor.length; j++)
{
GRPFColorFore[i][j] = createGRPF(i, j, GRPF.surface);
}
}+/
2015-07-07 22:21:01 +09:00
if(!exists(spriteFile))
{
writeln("download sprite");
download("http://smileboom.com/special/ptcm3/image/ss-story-attachment-1.png",
spriteFile);
}
if(!exists(BGFile))
{
writeln("download BG");
download("http://smileboom.com/special/ptcm3/image/ss-story-attachment-2.png",
BGFile);
}
if(!exists(fontTableFile))
{
writeln("create font table");
//HTMLなんて解析したくないから適当
createFontTable();
}
else
{
loadFontTable();
}
writeln("OK");
screenWidth = 400;
screenHeight = 240;
fontWidth = 8;
fontHeight = 8;
consoleWidth = screenWidth / fontWidth;
consoleHeight = screenHeight / fontHeight;
2015-07-11 22:21:48 +09:00
console = new ConsoleCharacter[][consoleHeight];
consoleForeColor = 15;//#T_WHITE
2015-07-07 22:21:01 +09:00
for(int i = 0; i < console.length; i++)
{
2015-07-11 22:21:48 +09:00
console[i] = new ConsoleCharacter[consoleWidth];
console[i][] = ConsoleCharacter(0, consoleForeColor, consoleBackColor);
}
}
void cls()
{
for(int i = 0; i < console.length; i++)
{
console[i][] = ConsoleCharacter(0, consoleForeColor, consoleBackColor);
2015-07-07 22:21:01 +09:00
}
}
SDL_Renderer* renderer;
int vsyncFrame;
int vsyncCount;
void vsync(int f)
{
vsyncCount = 0;
vsyncFrame = f;
}
int keybufferpos;
//解析した結果キー入力のバッファは127くらい
wchar[] keybuffer = new wchar[127];
void render()
{
bool renderprofile;
try
{
2015-08-18 17:45:21 +09:00
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
window = SDL_CreateWindow("SMILEBASIC", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, 400, 240,
2015-08-18 17:45:21 +09:00
/*SDL_WINDOW_SHOWN | */SDL_WINDOW_OPENGL);
renderer = SDL_CreateRenderer(window, -1, 0);
/*for(int i = 0; i < GRPFColor.length; i++)
{
GRPFColor[i].createTexture(renderer);
}*/
t8x8 = SDL_CreateTextureFromSurface(renderer, s8x8);
write("OK!");
SDL_Event event;
2015-08-18 17:45:21 +09:00
SDL_GLContext context;
context = SDL_GL_CreateContext(window);
GRPF.createTexture(renderer);
if (!context) return;
//glViewport(0, 0, 400, 240);
glClearColor(0.0f, 1.0f, 0.0f, 0.0f);
glEnable(GL_DEPTH_TEST);
while(true)
{
2015-08-18 17:45:21 +09:00
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
GLenum aa = glGetError();
glBindTexture( GL_TEXTURE_2D, GRPF.glTexture );
//glEnable(GL_BLEND);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glAlphaFunc(GL_GEQUAL, 0.5);
glEnable(GL_ALPHA_TEST);
aa = glGetError();
glBegin(GL_QUADS);
glTexCoord2f(1-0 , 1-0); glVertex2f(512/200f - 1, 1 - 512/120f);
glTexCoord2f(1-0 , 1-1); glVertex2f(512/200f - 1, 1);
glTexCoord2f(1-1 , 1-1); glVertex2f(-1, 1);
glTexCoord2f(1-1 , 1-0); glVertex2f(-1, 1 - 512/120f);
glEnd(); glFlush();
SDL_GL_SwapWindow(window);
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
SDL_DestroyWindow(window);
SDL_Quit();
return;
case SDL_KEYDOWN:
auto key = event.key.keysym.sym;
keybuffer[keybufferpos] = cast(wchar)key;
keybufferpos = (keybufferpos + 1) % keybuffer.length;
break;
default:
break;
}
}
continue;
auto profile = SDL_GetTicks();
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
renderConsole;
SDL_RenderPresent(renderer);
auto a = (SDL_GetTicks() - profile);
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
SDL_DestroyWindow(window);
SDL_Quit();
return;
case SDL_KEYDOWN:
auto key = event.key.keysym.sym;
keybuffer[keybufferpos] = cast(wchar)key;
keybufferpos = (keybufferpos + 1) % keybuffer.length;
break;
default:
break;
}
}
if(!renderprofile) writeln(a);
}
}
catch(Throwable t)
{
writeln(t);
}
}
SDL_Window* window;
2015-07-07 22:21:01 +09:00
void run()
{
init();
2015-07-06 23:09:15 +09:00
SDL_Init(SDL_INIT_VIDEO);
/+for(int i = 0; i < GRPFColor.length; i++)
{
for(int j = 0; j < GRPFColor.length; j++)
{
GRPFColorFore[i][j].createTexture(renderer);
}
}+/
//とりあえず
auto parser = new Parser(//readText("./SYS/EX1TEXT.TXT").to!wstring
//readText("FIZZBUZZ.TXT").to!wstring
readText("TEST.TXT").to!wstring
/*"?ABS(-1)
2015-07-11 22:21:48 +09:00
LOCATE 0,10
COLOR 5
FOR I=0 TO 10
?I;\"!\",\"=\",FACT(I)
NEXT
DEF FACT(N)
IF N<=1 THEN RETURN 1
RETURN N*FACT(N-1)
END"*/
/*
2015-07-11 22:21:48 +09:00
`CLS : CL=0 : Z=0
WHILE 1
INC Z : IF Z>200 THEN Z=0
FOR I=0 TO 15
LOCATE 9,4+I,Z : COLOR (CL+I) MOD 16
PRINT "★ 梅雨で雨が多い季節ですね ★"
NEXT
CL=(CL+1) MOD 16 : VSYNC 2
WEND`*/
/*
`CLS : CL=0
2015-07-12 12:17:01 +09:00
WHILE 1
FOR I=0 TO 15
LOCATE 9,4+I : COLOR (CL+I) MOD 16
PRINT "Ё プチコン3ゴウ Ж"
NEXT
CL=(CL+1) MOD 16 : VSYNC 1
WEND`
2015-07-12 12:17:01 +09:00
/*
`CLS : CL=0
@LOOP
FOR I=0 TO 15
LOCATE 9,4+I : COLOR (CL+I) MOD 16
PRINT "Ё プチコン3ゴウ Ж"
NEXT
CL=(CL+1) MOD 16 : VSYNC 1
2015-07-12 12:17:01 +09:00
GOTO @LOOP`*/
);
auto vm = parser.compile();
bool running = true;
vm.init(this);
consolem = new Mutex();
core.thread.Thread thread = new core.thread.Thread(&render);
thread.start();
auto startTicks = SDL_GetTicks();
2015-07-06 23:09:15 +09:00
while (true)
{
uint elapse;
startTicks = SDL_GetTicks();
do
{
try
{
if(!vsyncFrame && running) running = vm.runStep();
}
catch(SmileBasicError sbe)
{
running = false;
try
{
printConsole(sbe.to!string);
}
catch
{
}
2015-07-11 22:21:48 +09:00
}
catch(Throwable t)
{
running = false;
try
{
printConsole(t.to!string);
}
catch
{
}
2015-07-11 22:21:48 +09:00
}
elapse = SDL_GetTicks() - startTicks;
} while(elapse <= 1000 / 60);
vsyncCount++;
if(vsyncFrame <= vsyncCount) vsyncFrame = 0;
2015-07-06 23:09:15 +09:00
}
SDL_DestroyWindow(window);
SDL_Quit();
}
wstring input(wstring prompt, bool useClipBoard)
{
printConsole(prompt);
return "";
}
2015-07-07 22:21:01 +09:00
int CSRX;
int CSRY;
int CSRZ;
2015-07-11 22:21:48 +09:00
int consoleForeColor, consoleBackColor;
Mutex consolem;
2015-07-07 22:21:01 +09:00
void renderConsole()
{
consolem.lock();
scope(exit) consolem.unlock();
2015-07-07 22:21:01 +09:00
for(int y = 0; y < consoleHeight; y++)
for(int x = 0; x < consoleWidth; x++)
{
SDL_Rect rect = SDL_Rect(x * 8, y * 8, 8, 8);
2015-07-11 22:21:48 +09:00
auto fore = consoleColor[console[y][x].foreColor];
auto back = consoleColor[console[y][x].backColor];
SDL_SetTextureColorMod(t8x8, back >> 16 & 0xFF, back >> 8 & 0xFF, back & 0xFF);
SDL_SetTextureAlphaMod(t8x8, back >> 24 & 0xFF);
SDL_RenderCopy(renderer, t8x8, null, &rect);
/*
auto texture = GRPFColor[back].texture;
auto back = console[y][x].backColor;
SDL_RenderCopy(renderer, texture, &fontTable[console[y][x].charater], &rect);*/
2015-07-11 22:21:48 +09:00
SDL_SetTextureColorMod(GRPF.texture, fore >> 16 & 0xFF, fore >> 8 & 0xFF, fore & 0xFF);
SDL_SetTextureAlphaMod(GRPF.texture, fore >> 24 & 0xFF);
SDL_RenderCopy(renderer, GRPF.texture, &fontTable[console[y][x].charater], &rect);
/*
auto back = console[y][x].backColor;
auto fore = console[y][x].foreColor;
auto texture = GRPFColorFore[back][fore].texture;
SDL_RenderCopy(renderer, texture, &fontTable[console[y][x].charater], &rect);*/
/*
auto back = consoleColor[console[y][x].backColor];
auto texture = GRPFColor[back].texture;
SDL_RenderCopy(renderer, texture, &fontTable[console[y][x].charater], &rect);
texture = GRPF.texture;
//SDL_SetRenderDrawColor(renderer, back >> 16 & 0xFF, back >> 8 & 0xFF, back & 0xFF, back >> 24 & 0xFF);
//SDL_RenderFillRect(renderer, &rect);
auto fore = consoleColor[console[y][x].foreColor];
SDL_SetTextureColorMod(texture, fore >> 16 & 0xFF, fore >> 8 & 0xFF, fore & 0xFF);
SDL_SetTextureAlphaMod(texture, fore >> 24 & 0xFF);
SDL_RenderCopy(renderer, texture, &fontTable[console[y][x].charater], &rect);*/
2015-07-07 22:21:01 +09:00
}
}
void printConsole(T...)(T args)
{
foreach(i; args)
{
printConsoleString(i.to!wstring);
}
}
void printConsoleString(wstring text)
2015-07-07 22:28:30 +09:00
{
consolem.lock();
scope(exit) consolem.unlock();
//write(text);
2015-07-07 22:28:30 +09:00
foreach(wchar c; text)
{
if(CSRY >= consoleHeight)
{
CSRY = consoleHeight - 1;
}
2015-07-07 22:28:30 +09:00
if(c != '\r' && c != '\n')
{
2015-07-11 22:21:48 +09:00
console[CSRY][CSRX].charater = c;
console[CSRY][CSRX].foreColor = consoleForeColor;
console[CSRY][CSRX].backColor = consoleBackColor;
2015-07-07 22:28:30 +09:00
}
CSRX++;
if(CSRX >= consoleWidth || c == '\n' || c == '\r')
{
CSRX = 0;
CSRY++;
}
if(CSRY >= consoleHeight)
{
auto tmp = console[0];
for(int i = 0; i < consoleHeight - 1; i++)
{
console[i] = console[i + 1];
}
console[consoleHeight - 1] = tmp;
2015-07-11 22:21:48 +09:00
tmp[] = ConsoleCharacter(0, consoleForeColor, consoleBackColor);
//assert(console[0] != console[2]);
CSRY = consoleHeight - 1;
}
2015-07-07 22:28:30 +09:00
}
}
}
import std.typecons;
import std.typetuple;
import std.traits;
import otya.smilebasic.error;
import otya.smilebasic.type;
static string func;
class Test
{
import otya.smilebasic.type;
int a;/*
static Value abs(Value[] a)
{
return Value((a[0].castDouble < 0 ? -a[0].castDouble : a[0].castDouble));
}*/
static double ABS(double a)
{
return a < 0 ? -a : a;
}
wstring[] ah;
void*[] ahe;
alias void function(Value[], Value[]) BuiltinFunc;
BuiltinFunc[] builtinFunctions;
this()
{
foreach(name; __traits(derivedMembers, Test))
{
//writeln(name);
ah ~= name;
// foreach (t; __traits(getVirtualFunctions, Test, name))
{
static if(__traits(isStaticFunction, __traits(getMember, Test, name)))
{
ahe ~= cast(void*)&__traits(getMember, Test, name);
writeln(name);
auto m = typeid(typeof(__traits(getMember, Test, name)));
writeln(m);
writeln(AddFunc!(Test,name));
builtinFunctions ~= mixin(AddFunc!(Test,name));
}
}
}
}
}
template AddFunc(T, string N)
{
static if(is(ReturnType!(__traits(getMember, T, N)) == double))
{
const string AddFunc = "function void(Value[] arg, Value[] ret){if(ret.length != 1){throw new IllegalFunctionCall();}ret[0] = Value(" ~ N ~ "(" ~
AddFuncArg!(Tuple!(ParameterTypeTuple!(__traits(getMember, T, N))), 0) ~ "));}";
}
else
{
const string AddFunc = "";
}
}
template AddFuncArg(P, int N = 0)
{
static if(is(typeof(P[N]) == double))
{
const string arg = "arg[" ~ N.to!string ~ "].castDouble";
}
else
{
const string arg = "";
static assert(false, "Invalid type");
}
static if(N + 1 == P.length)
{
const string AddFuncArg = arg;
}
else
{
const string AddFuncArg = arg ~ ", " ~ AddFuncArg!(P, N + 1);
}
}