8月18日(周六)成都源创会火热报名中,四位一线行业大牛与你面对面,探讨区块链技术热潮下的冷思考。
Watch Star Fork

git123hub / luajit-testC/C++

加入码云
与超过 300 万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
暂无描述
一键复制 编辑 原始数据 按行查看 历史
luaconsole_SDL.bat 30.30 KB My main account 提交于 2018-08-01 11:39 . Add files via upload
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149
:: How to get SDL: click https://starcatcher.us/TPT/MingwLibraries.zip to download
:: SDL means "Simple DirectMedia Layer"
@echo off
:: chcp 437 >nul & graftabl 936 >nul
md tmp 2>nul
more +35 %0 > tmp\%~n0.cpp
if not "%1"=="debug" (
set coptimize=-O3 -msse -msse2 -ffast-math -D_SDL
set cxxoptimize=-Wno-invalid-offsetof -msse -msse2 -O3 -ftree-vectorize -funsafe-math-optimizations -ffast-math -fomit-frame-pointer -funsafe-loop-optimizations -D_SDL
) else (
set coptimize=-Wall -g -DDEBUG -D_SDL
set cxxoptimize=-Wno-invalid-offsetof -msse -msse2 -Wall -g -DDEBUG -D_SDL
)
gcc -c -o tmp\bitop.o bitop.c %coptimize%
fasm lua-proc-asm.asm tmp\lua-proc-asm.o >nul
g++ -c -o tmp\event.o event.cpp %cxxoptimize%
g++ -c -o tmp\strop.o strop.cpp %cxxoptimize%
g++ -c -o tmp\rng32.o rng32.cpp %cxxoptimize% -std=gnu++11
g++ -c -o tmp\common-func.o common\func.cpp %cxxoptimize%
g++ -c -o tmp\conwin.o lua-conwin.cpp %cxxoptimize%
g++ -c -o tmp\lua-attrib.o lua-attrib.cpp %cxxoptimize%
g++ -c -o tmp\lua-conxlat.o lua-conxlat.cpp %cxxoptimize%
g++ -c -o tmp\lua-font.o lua-font.cpp %cxxoptimize%
g++ -c -o tmp\lua-int32.o lua-int32.cpp %cxxoptimize%
g++ -c -o tmp\cmdargs.o cmdargs.cpp %cxxoptimize%
g++ -c -o tmp\%~n0.o tmp\%~n0.cpp %cxxoptimize% -std=gnu++11
g++ tmp\*.o -o %~n0.exe -Wl,-Bstatic -static-libgcc -lluajit -lmingw32 -lm -lSDLmain -lSDL -lwinmm -mwindows -Wno-unused-result
:: rd /s /q tmp
if not "%1"=="debug" (
strip %~n0.exe
)
%~n0.exe
pause > nul
goto :eof
#include <iostream>
#include <string>
#include <cstdlib>
// #include <stack>
#include <queue>
#include <map>
#include <SDL/SDL.h>
#include <csetjmp>
#include "../console-common.h"
#include "../lua-font.h"
#include "../ascii-font.cpp"
#include "../lua-conwin.h"
#include "../lua-attrib.h"
#include "../lua-debug-funcs.h"
#include "../lua-extra-attr.h"
#include "../lua-fn-aliases.h"
#include "../lua-render-ex.h"
#define USE_FASM
#ifdef DEBUG
# ifdef _WIN64
# pragma message ("default CS register is 0x0033")
# elif defined(_WIN32)
# pragma message ("default CS register is 0x0023")
# endif
#endif
#if defined(_WIN32) && !defined(_WIN64) && defined(__GNUC__) && defined(X86)
# define USE_GCC_WIN32
#endif
void read_cmd_arg(lua_State * L, char * arg, bool * k, int * f, int * p, int c, char ** v);
void sdl_decrement_timeout();
#define cmd_preset_color __static_cmd_preset_color
// Using CMD's color <attr>
static int cmd_preset_color[16] = {
0x000000, 0x000080, 0x008000, 0x008080, 0x800000, 0x800080, 0x808000, 0xC0C0C0,
0x808080, 0x0000FF, 0x00FF00, 0x00FFFF, 0xFF0000, 0xFF00FF, 0xFFFF00, 0xFFFFFF,
};
extern "C" int luaopen_bit(lua_State *L);
int luacon_extend_str_api(lua_State *L);
int luarng_init_(lua_State *L);
int input_chars = 0, input_pos = 0, first_input_line = 0, lua_cursor = 1,
tmp_input_pos_0 = 0, attr_stack_base_pointer;
// lua_State * primary_state, * lua_subthread_state;
bool fullscreened = false,
fullscreen_wait = false,
enable_fullscreen_shortcut = true;
#define altflags luaevent_altkey_flags
#define text_buf luacon_text_buffer
int altflags = (
ALT_CAN_ENABLE |
ALT_ECHO_INPUT
);
SDL_Surface *sdl_scrn;
// std::stack <int>
std::vector <int> attr_stack;
std::vector <int*> luacon_thread_handles;
std::queue <std::string> lua_proc_func_queue;
int32_t *text_buf = NULL, *luacon_mask_table_0 = NULL;
std::vector <int32_t*> semigraphics_bufs;
char *input_buffer = NULL, *input_buffer2 = NULL;
fontdata_t *ascii_font_ptr = NULL;
HANDLE MainThreadHandle = (HANDLE)0;
_MY_HANDLE_STATUS ScriptThreadHandle
#ifdef __GNUC__
__attribute__ ((aligned (16))) // must be aligned
#endif
= {NULL, 0};
int curr_fg = DEFAULT_FGCOLOR, curr_bg = DEFAULT_BGCOLOR,
gfx_index = 0, tmp_gfx_index = 0, tmp_gfx_index_2 = 0;
std::string luacon_lastCode_v;
#define lastCode luacon_lastCode_v // it's variable, not a function
int luacon_writeTableError(lua_State* L)
{
return luaL_error(L, "attempt to update a read-only table");
}
void sdl_scrn_setcursor(unsigned int * vid)
{
bool curs = altflags & ALT_HAS_CURSOR;
if ((gfx_index == 0 || curs) && lua_cursor)
{
lua_cursor++;
if (lua_cursor > 60) lua_cursor = 1;
int c, r, i, j;
if (curs)
r = ALT_STATUS_LINE, c = tmp_input_pos_0 + 1;
else
c = input_pos, r = first_input_line + c / XCHRS,
c %= XCHRS;
if (lua_cursor > 30)
{
for (i = 0; i < CHRW; i++)
for (j = CHRH-(CHRH/4); j < CHRH; j++)
vid[(c*CHRW+i)+(XRES)*(r*CHRH+j)] = ~vid[(c*CHRW+i)+(XRES)*(r*CHRH+j)];
}
}
}
void sdl_blit(int x, int y, int w, int h, unsigned int *src, int pitch)
{
unsigned *dst;
int i, j;
if (SDL_MUSTLOCK(sdl_scrn))
if (SDL_LockSurface(sdl_scrn)<0)
return;
dst = (unsigned *)sdl_scrn->pixels+y*sdl_scrn->pitch/4+x;
for (j = 0; j < h; j++)
{
for (i = 0; i < w; i++)
dst[i] = src[i];
dst += sdl_scrn->pitch/4;
src += pitch/4;
}
if (SDL_MUSTLOCK(sdl_scrn))
SDL_UnlockSurface(sdl_scrn);
SDL_UpdateRect(sdl_scrn,0,0,0,0);
}
void reverse_buffer_int32 (int32_t * buf, int len)
{
int half = len / 2, tmp, i;
for (i = 0; i < half; i++)
{
tmp = buf[i];
buf[i] = buf[len-i-1];
buf[len-i-1] = tmp;
}
#ifdef DEBUG
std::cout << &buf[0]-text_buf << ", " << &buf[len]-text_buf << std::endl;
std::cout << i << std::endl;
#endif
}
#define luaL_identity lua_gettop
#define TAB_SIZE 8
int sdl_stdout (const char* str, int len = -1)
{
int tmp_fgc = curr_fg, k = first_input_line;
int tmp, i, j, upshift, chr;
bool wrap = false, revvid = false;
#if FONT_NUM_CHAR_BITS >= 9
int tmpoff = 0x100;
#endif
if (len == -1)
len = strlen(str);
for (i = 0, j = 0; i < len; i++)
{
switch (str[i])
{
case '\t': j += TAB_SIZE - j % TAB_SIZE; break;
case '\n': j = XCHRS; break;
case '\x0F':
i += 3; if (i >= len) goto end_of_loop;
curr_fg = ((str[i-2] & 0xFF) << 16) | ((str[i-1] & 0xFF) << 8) | (str[i] & 0xFF);
break;
case '\x0E':
curr_fg = tmp_fgc;
break;
#if FONT_NUM_CHAR_BITS >= 9
case '\x0B':
if (++i >= len) goto end_of_loop;
chr = tmpoff | (str[i] & 0xFF);
goto extra_char_0;
break;
#endif
case '\x11':
tmp = (unsigned char)(str[++i]);
switch (tmp >> 3)
{
case 5:
#if FONT_NUM_CHAR_BITS >= 10
if (tmp < 0x2A)
{
tmpoff += (tmp == 0x28) ? 0x100 : -0x100;
tmpoff %= FONT_NUM_CHARS - 0x100;
while (tmpoff < 0x100) tmpoff += FONT_NUM_CHARS - 0x100;
}
else if (tmp == '/')
{
tmpoff = 0x100;
}
#endif
break;
case 6: case 7: // 0x30-0x39 = number part
if (tmp <= '9') curr_fg = cmd_preset_color[tmp - '0'];
break;
case 8: case 12: // 0x41-0x5A, 0x61-0x7A = alphabetic part
{
char _tmp = tmp & 7; // e.g. 0x41 = 'A'
if (_tmp != 0 && _tmp != 7) curr_fg = cmd_preset_color[_tmp + 9];
}
break;
case 16: case 17: case 18: case 19: // 0x80-0x9F: used as "blockic" mode
chr = tmp & 0x1F;
goto extra_char_0;
}
break;
case '\x12': // reverse video
revvid = !revvid;
break;
default:
chr = str[i] & 0xFF;
// #if FONT_NUM_CHAR_BITS >= 9
extra_char_0:
// #endif
if (revvid)
drawchr_inv(text_buf, j, k, chr);
else
drawchr(text_buf, j, k, chr);
j++;
}
if (j >= XCHRS)
{
k++; j = 0;
if (k >= YCHRS) wrap = true, k -= YCHRS;
if (wrap) clear_line(text_buf, k);
}
}
end_of_loop:
first_input_line = (k + 1) % YCHRS;
curr_fg = tmp_fgc;
if (first_input_line != 0 && !wrap) return 0;
if (first_input_line != YCHRS-1)
{
upshift = first_input_line + 1;
reverse_buffer_int32 (text_buf, (SSKIP/4) *XCHRS*upshift);
reverse_buffer_int32 (text_buf+ (SSKIP/4) *XCHRS*upshift, (SSKIP/4)*XCHRS*(YCHRS-upshift));
reverse_buffer_int32 (text_buf, (SSKIP/4) *XCHRS*YCHRS);
first_input_line = YCHRS-1;
// std::cout << upshift << std::endl;
}
clear_line(text_buf, YCHRS-1);
return 0;
}
#define sdl_stderr sdl_stdout
static int __lua_restart_prog (lua_State * l)
{
#if defined(X86) && defined(__GNUC__)
__sync_fetch_and_or(&altflags, ALT_RESTART_PROG);
#else
EnterCriticalSection(&luacon_critical_0);
altflags |= ALT_RESTART_PROG;
LeaveCriticalSection(&luacon_critical_0);
#endif
return 0;
}
int luaL_optint_gfx_i(lua_State * L, int n)
{
int i = luaL_optint(L, n, gfx_index);
if (IS_FREED_BUFF(i, semigraphics_bufs))
i = gfx_index;
return i;
}
const char* lua_tostring_ext (lua_State * L, int n)
{
switch (lua_type(L, n))
{
case LUA_TNUMBER:
case LUA_TSTRING:
return lua_tostring(L, n);
case LUA_TBOOLEAN:
return (lua_toboolean(L, n) ? "true" : "false");
break;
case LUA_TNIL:
return "nil";
default:
lua_pushfstring(L, "%s: %p", luaL_typename(L, n), lua_topointer(L, n));
const char* s = lua_tostring(L, -1);
lua_pop(L, 1);
return s;
}
}
int luacolor_cmd2rgb (lua_State * l)
{
int cmd_attr = luaL_checkint(l, 1);
lua_pushinteger(l, cmd_preset_color[cmd_attr & 0xF]);
lua_pushinteger(l, cmd_preset_color[(cmd_attr >> 4) & 0xF]);
return 2;
}
int luacolor_photwl2rgb (lua_State * L)
{
uint32_t x = luaL_checkinteger(L, 1);
static const uint64_t m = 0x4332322132212110LL;
int r, g, b, i;
for (i = 0; i < 12; i += 4)
r += (m >> 4 * ((x >> (i + 18)) & 0xF)) & 0xF,
g += (m >> 4 * ((x >> (i + 9)) & 0xF)) & 0xF,
b += (m >> 4 * ((x >> (i + 0)) & 0xF)) & 0xF;
i = 624 / (r + g + b + 1);
r *= i; (r > 255) && (r = 255);
g *= i; (g > 255) && (g = 255);
b *= i; (b > 255) && (b = 255);
lua_pushinteger(L, (r<<16) | (g<<8) | b);
return 1;
}
int luacolor_rgb (lua_State * l)
{
int red = luaL_checkint(l, 1);
int green = luaL_checkint(l, 2);
int blue = luaL_checkint(l, 3);
clamp_int8(red)
clamp_int8(green)
clamp_int8(blue)
lua_pushinteger(l, (red<<16)|(green<<8)|blue);
return 1;
}
int lua_alloc_subcon (lua_State * l)
{
lua_pushboolean(l, AllocConsole());
SetConsoleTitle("Lua subconsole");
return 1;
}
int lua_free_subcon (lua_State * l)
{
lua_pushboolean(l, FreeConsole());
return 1;
}
int luacon_output (lua_State * l)
{
int args = lua_gettop(l);
int tmp_fgc, tmp_bgc, tmp_arg;
const char *tmp_str;
size_t tmp_len;
if (args >= 1)
{
if (args >= 2)
{
tmp_fgc = curr_fg;
tmp_bgc = curr_bg;
tmp_arg = luaL_checkinteger(l, 2);
curr_bg = args >= 3 ? luaL_checkinteger(l, 3) : tmp_bgc;
curr_fg = tmp_arg;
}
if (lua_type(l, 1) == LUA_TSTRING)
tmp_str = lua_tolstring(l, 1, &tmp_len), sdl_stdout(tmp_str, tmp_len);
else
sdl_stdout(lua_tostring_ext(l, 1));
if (args >= 2)
{
curr_fg = tmp_fgc;
curr_bg = tmp_bgc;
}
}
return 0;
}
int lua_write_subcon (lua_State * l)
{
HANDLE HConsole = GetStdHandle(STD_OUTPUT_HANDLE);
const char* str = lua_tostring_ext(l, 1);
WriteConsole(HConsole, str, strlen(str), NULL, NULL);
return 0;
}
#define luacon_to_bound(begin, end, max)\
if (begin < 0) begin = 0;\
if (end > (max)) end = (max);
static int __luacon_drawchr_general (lua_State * l, void (*fn)(int32_t*, int, int, int))
{
int args = lua_gettop(l);
int arg1, // character
arg2, // position x
arg3, // position y
arg4, // number of times to write
arg5, // window page
endx, i;
if (args >= 3)
luaL_va_tointegers (l, 2, &arg2, &arg3, NULL);
else
return luaL_error(l, "Must be least 3 arguments");
arg4 = luaL_optint(l, 4, 1);
arg5 = luaL_optint_gfx_i(l, 5);
switch (lua_type(l, 1))
{
case LUA_TNUMBER:
arg1 = lua_tointeger(l, 1);
break;
case LUA_TSTRING:
arg1 = lua_tostring(l, 1)[0] & 0xFF;
break;
default:
return luaL_error(l, "argument #1 must be number or string");
break;
}
int32_t* buf = semigraphics_bufs[arg5];
if (arg4 < 0) arg4 = 0;
if (arg3 >= 0 && arg3 < YCHRS)
{
endx = arg2 + arg4;
luacon_to_bound(arg2, endx, XCHRS);
for (i = arg2; i < endx; i++)
fn(buf, i, arg3, arg1);
}
return 0;
}
int luacon_drawchr (lua_State * L)
{
return __luacon_drawchr_general(L, drawchr);
}
int luacon_drawchr_inv (lua_State * L)
{
return __luacon_drawchr_general(L, drawchr_inv);
}
int luacon_readchr (lua_State * l)
{
int args = lua_gettop(l);
int x, y, f, p, ra, beg;
if (args >= 2)
x = lua_tointeger(l, 1),
y = lua_tointeger(l, 2);
else
return luaL_error(l, "Must be least 2 arguments");
f = luaL_optint(l, 3, 0);
p = luaL_optint_gfx_i(l, 4);
ra = (f & FLAG_READ_ATTR) ? 3 : 1;
beg = (SSKIP/4) * (y*(XCHRS)+x);
for (int i = 0; i < ra; i++)
if (IN_CONSOLE(x, y))
lua_pushinteger(l, semigraphics_bufs[p][beg + i]);
else
lua_pushnil(l);
return ra;
}
int luacon_cls (lua_State * L)
{
int arg1 = luaL_optint_gfx_i(L, 1);
clear_line(semigraphics_bufs[arg1], 0, YCHRS);
if (arg1 == 0)
{
first_input_line = 0;
}
return 0;
}
int luacon_cls_ex (lua_State * L)
{
luacon_cls(L);
if (lua_toboolean(L, 2))
luacon_scrn_clear_blink(L);
return 0;
}
int luacon_getcondata (lua_State * l)
{
int p = luaL_optint_gfx_i(l, 5), x, y, w, h;
int *(args[]) = {&x, &y, &w, &h, NULL},
argvalue[] = {0, 0, XCHRS, YCHRS};
luaL_va_optints(l, 1, args, argvalue);
if (w < 0 || h < 0 || w > XCHRS || h > YCHRS)
return luaL_error(l, "Size out of range");
int32_t *src = semigraphics_bufs[p],
*dst = (int32_t*)lua_newuserdata (l, w * h * SSKIP + 4); // canvas size + 4 byte
*dst = (w & 0xFFFF) | ((h & 0xFFFF) << 16); dst++;
int x1 = x, y1 = y, x2 = x + w, y2 = y + h, sz;
luacon_to_bound (x1, x2, XCHRS);
luacon_to_bound (y1, y2, YCHRS);
x1 *= SSKIP/4, x2 *= SSKIP/4, x *= SSKIP/4, sz = x2-x1;
for (int i = y1; i < y2; i++)
memcpy(&dst[(i-y)*w*(SSKIP/4)+(x1-x)], &src[i*XCHRS*(SSKIP/4)+x1], sz<0?0:sz);
return 1;
}
int luacon_setcondata (lua_State * l)
{
// int args = lua_gettop(l);
if (lua_type(l, 1) != LUA_TUSERDATA)
return luaL_error(l, "argument #1 must be userdata");
int len = luaL_getn(l, 1);
int x = luaL_optint(l, 2, 0);
int y = luaL_optint(l, 3, 0);
int p = luaL_optint_gfx_i(l, 4);
int32_t *src = (int32_t*)lua_touserdata(l, 1),
*dst = semigraphics_bufs[p];
int w = *src & 0xFFFF, h = (*src >> 16) & 0xFFFF;
src++;
if (len != w * h * SSKIP + 4 || w > XCHRS || h > YCHRS)
return luaL_error(l, "set console data error");
int x1 = x, y1 = y, x2 = x + w, y2 = y + h, sz;
luacon_to_bound (x1, x2, XCHRS);
luacon_to_bound (y1, y2, YCHRS);
x1 *= SSKIP/4, x2 *= SSKIP/4, x *= SSKIP/4, sz = x2-x1;
for (int i = y1; i < y2; i++)
memcpy(&dst[i*XCHRS*(SSKIP/4)+x1], &src[(i-y)*w*(SSKIP/4)+(x1-x)], sz<0?0:sz);
return 0;
}
#undef luacon_to_bound
#define MAX_LEN (XCHRS-24)
int sdl_poll(bool* entered)
{
if (altflags & (ALT_ERR_RUN2 | ALT_RESTART_PROG)) return 1;
EnterCriticalSection(&luacon_critical_0);
static char cmd [MAX_LEN + 1];
SDL_Event event;
int sdl_key = 0, unicode = 0, return_value = 0;
bool tmp_entered = false;
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_KEYDOWN:
sdl_key = event.key.keysym.sym;
unicode = event.key.keysym.unicode;
altflags &= ~ALT_PRESSING;
if (sdl_key == SDLK_LALT || sdl_key == SDLK_RALT)
altflags |= ALT_PRESSING;
if (sdl_key == SDLK_KP_ENTER || sdl_key == SDLK_RETURN)
tmp_entered = true;
*entered = console_event_process(sdl_key, unicode, event.key.keysym.mod, text_buf, tmp_entered, &return_value, cmd);
if (tmp_entered)
goto retn;
break;
case SDL_KEYUP:
sdl_key = event.key.keysym.sym;
SDL_console_key_release(sdl_key, event.key.keysym.mod);
if (sdl_key == SDLK_LALT || sdl_key == SDLK_RALT)
{
char f = altflags;
if (f & ALT_PRESSING)
{
altflags &= ~ALT_PRESSING;
if (f & ALT_CAN_ENABLE && !luacon_altmenu_suspend_count)
altflags ^= ALT_ENABLED,
console_altmode_call(f & ALT_ENABLED, cmd); // false = enabling, true = disabling
}
}
break;
case SDL_QUIT:
return_value = 1;
goto retn;
}
}
retn:
if (altflags & ALT_ENABLED)
{
SDL_add_status_bar (semigraphics_bufs[gfx_index]);
}
LeaveCriticalSection(&luacon_critical_0);
return return_value;
}
int luacon_wait (lua_State * l)
{
int time = luaL_checkint(l, 1);
SDL_Delay(time);
return 0;
}
static bool input_script_flag = true;
int lua_proc_push_func (lua_State * L, char* add_str, HANDLE evt)
{
lua_proc_func_queue.push(std::string(add_str));
if (evt != NULL)
SetEvent(evt);
return 0;
}
#define luaL_custom_struct_0(name) \
struct name { \
lua_State *L;\
_MY_HANDLE_STATUS *h;\
bool *input_script_flag;\
HANDLE sync;\
DWORD sync_tid;\
}
static std::map <intptr_t, intptr_t> __luacon_panic_throw_bufs; // <lua_State*, jmp_buf*>
#ifdef USE_GCC_WIN32
# define MY_SEH_BEGIN(f) \
do { \
long * _seh_head = __builtin_alloca (12);\
__asm__ __volatile__ ("\
mov {%%fs:0, %%eax|eax, fs:[0]}\n\
mov {%%eax, (%0)|[%0], eax}\n\
lea {%1, %%eax|eax, %1}\n\
mov {%%eax, 4(%0)|[%0+4], eax}\n\
mov {%2, 8(%0)|[%0+8], %2}\n\
mov {%0, %%fs:0|fs:[0], %0}"\
:: "r"(_seh_head), "m"(f), "r"(L)\
: "eax", "memory"\
);
# define MY_SEH_END \
__asm__ __volatile__ (\
"mov {%0, %%fs:0|fs:[0], %0}"\
:: "r"(*_seh_head)\
: "eax", "memory"\
); \
}
# define USE_GCC_WIN32
#endif
#if defined(MY_SEH_BEGIN) && defined(USE_FASM)
__attribute__((regparm(2)))
int __luacon_process_pcall_arg (lua_State * L, int arg) __asm__(".luacon_process_pcall");
__attribute__((regparm(3)))
void __luacon_swap64_asm (void*, void*, void*) __asm__(".luacon_swap64");
#define __luacon_process_pcall(L) __luacon_process_pcall_arg(L, LUA_MULTRET)
#else
# ifndef MY_SEH_BEGIN
# define MY_SEH_BEGIN(f) {
# define MY_SEH_END }
# endif
__declspec(noinline)
int __luacon_process_pcall_exception (void)
{
return 1;
}
int __luacon_process_pcall (lua_State * L)
{
MY_SEH_BEGIN(__luacon_process_pcall_exception)
return lua_pcall(L, 0, LUA_MULTRET, 0);
MY_SEH_END
}
#endif
int lua_process (void *_st)
{
luaL_custom_struct_0(st0) *st = (st0 *)_st;
int level;
lua_State *L = st->L;
void * panicbuf = (void*)(__luacon_panic_throw_bufs[(intptr_t)L]);
if (setjmp(*(jmp_buf*)panicbuf))
{
#ifdef __GNUC__
__sync_fetch_and_or(&altflags, ALT_ERR_RUN2);
#else
EnterCriticalSection(&luacon_critical_0);
altflags |= ALT_ERR_RUN2;
#endif
free(panicbuf);
#ifndef __GNUC__
LeaveCriticalSection(&luacon_critical_0);
#endif
CloseHandle(st->sync);
return 0;
}
for (;;)
{
WaitForSingleObject(st->sync, INFINITE);
/*
if (GetCurrentThreadId() != st->sync_tid)
continue;
*/
EnterCriticalSection(&luacon_critical_0);
if (lua_proc_func_queue.empty())
{
LeaveCriticalSection(&luacon_critical_0);
continue;
}
std::string add_str = lua_proc_func_queue.front();
lua_proc_func_queue.pop();
LeaveCriticalSection(&luacon_critical_0);
int save_top = lua_gettop(L);
if (!*(st->input_script_flag))
{
int retc = luaL_loadfile(L, add_str.c_str());
if (!retc)
retc = __luacon_process_pcall(L);
*(st->input_script_flag) = true;
}
else
{
if (lastCode.length())
lastCode += "\n";
lastCode += add_str;
std::string tmp = "return " + lastCode;
luaL_loadbuffer(L, tmp.c_str(), tmp.length(), "@console");
if (lua_type(L, -1) != LUA_TFUNCTION)
{
lua_pop(L, 1);
luaL_loadbuffer(L, lastCode.c_str(), lastCode.length(), "@console");
}
if (lua_type(L, -1) != LUA_TFUNCTION)
{
std::string err = lua_tostring_ext(L, -1);
if (err.find("near '<eof>'") != err.npos) //the idea stolen from lua-5.1.5/lua.c
sdl_stdout("...", 3);
else
{
sdl_stderr(err.c_str());
lastCode = "";
}
}
else
{
lastCode = "";
int retc = __luacon_process_pcall(L);
if (retc)
{
luacon_reg_clearupmem(L);
sdl_stderr(lua_tostring_ext(L, -1));
}
else
{
int top = lua_gettop(L); size_t l; const char * s;
for (level = save_top + 1; level <= top; level++)
if (lua_type(L, level) == LUA_TSTRING)
s = lua_tolstring(L, level, &l), sdl_stdout(s, l);
else
sdl_stdout(lua_tostring_ext(L, level));
}
}
}
lua_settop(L, save_top);
}
// lua_close(L);
return 0;
}
#define STACK_SIZE (1 << 11)
static int __luacon_read_handles (lua_State* L)
{
int i = luaL_optinteger(L, 2, 0), v = 0;
if (i >= 0 && i < (int)luacon_thread_handles.size())
v = *(luacon_thread_handles[i]);
lua_pushinteger(L, v);
return 1;
}
static void __luacon_render_process (int * first_tick, unsigned * vid)
{
EnterCriticalSection(&luacon_critical_0);
if (fullscreen_wait)
{
SDL_ShowCursor(!fullscreened);
SDL_SetVideoMode(XRES, YRES, 32, SDL_SWSURFACE | (fullscreened ? SDL_FULLSCREEN : 0));
fullscreen_wait = false;
}
LeaveCriticalSection(&luacon_critical_0);
*first_tick += 20;
int last_tick = SDL_GetTicks();
int delay = *first_tick - last_tick;
if (delay > 0)
SDL_Delay(delay);
else
{
SwitchToThread();
*first_tick = last_tick;
}
EnterCriticalSection(&luacon_critical_0);
sdl_translate_map(semigraphics_bufs[gfx_index], vid, altflags);
sdl_scrn_setcursor(vid);
sdl_decrement_timeout();
sdl_blit(0, 0, XRES, YRES, vid, XRES*4);
LeaveCriticalSection(&luacon_critical_0);
}
static int __luacon_panic_throw (lua_State* L)
{
longjmp(*(jmp_buf*)(__luacon_panic_throw_bufs[(intptr_t)L]), 1);
}
intptr_t luacon_stateRegTable[2 * REG_MAX_LUA_STATES];
int main (int argc, char** argv)
{
int i, exit_status = 0;
text_buf = (int32_t*)malloc(XCHRS*YCHRS*SSKIP);
SDL_curr_status = (char*)malloc(XCHRS + (1<<7));
for (i = 0; i < XCHRS*YCHRS*(SSKIP/4); i++)
text_buf[i] = 0;
for (i = 0; i < REG_MAX_LUA_STATES; i++)
{
luacon_stateRegTable[2*i] = (intptr_t)NULL;
}
luacon_mask_table_0 = (int32_t*)malloc(4*(XCHRS*YCHRS*2+1));
luacon_mask_table_0[0] = -1;
for (i = 0; i < XCHRS*YCHRS; i++)
luacon_mask_table_0[2*i+1] = -1,
luacon_mask_table_0[2*i+2] = 0;
const static int attr_init[4] = {4, STACK_SIZE, DEFAULT_FGCOLOR, DEFAULT_BGCOLOR};
attr_stack.reserve(STACK_SIZE);
for (i = 0; i < 4; i++)
attr_stack.push_back(attr_init[i]);
attr_stack_base_pointer = attr_stack.size();
attr_stack.resize(STACK_SIZE);
semigraphics_bufs.reserve(1 << 9);
semigraphics_bufs.push_back(text_buf);
unsigned * vid = (unsigned*)calloc(XRES*YRES, sizeof(unsigned));
if (SDL_Init(SDL_INIT_VIDEO)<0)
{
fprintf(stderr, "Initializing SDL: %s\n", SDL_GetError());
exit(1);
}
atexit(SDL_Quit);
sdl_scrn = SDL_SetVideoMode(XRES, YRES, 32, SDL_SWSURFACE);
if (!sdl_scrn)
{
fprintf(stderr, "Creating window: %s\n", SDL_GetError());
exit(1);
}
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
SDL_EnableUNICODE(1);
SDL_WM_SetCaption( "Lua console", NULL );
char* chr_buffer = (char*)malloc(XCHRS * (YCHRS-1) + 1);
input_buffer = chr_buffer;
char* chr_buffer2 = (char*)malloc(XCHRS * (YCHRS-1) + 1);
input_buffer2 = chr_buffer2;
ascii_font_ptr = (fontdata_t *)calloc(FONT_NUM_CHARS, sizeof(intptr_t));
for (i = 0; i < 95; i++)
ascii_font_ptr[i+32] = (fontdata_t)ascii_font[i];
bool is_quit;
lua_State *L = luacon_regnewstate();
if (L == NULL)
exit(1);
luacon_initCriticals();
luaL_openlibs(L);
lua_atpanic(L, __luacon_panic_throw);
lua_pushcfunction(L, luacon_output);
lua_setglobal(L, "print");
const static struct luaL_Reg console_lua_api [] = {
{"get_data", luacon_getcondata},
{"put_data", luacon_setcondata},
{"draw_char", luacon_drawchr},
{"draw_char_inv", luacon_drawchr_inv},
{"draw_char_decode", luacon_drawchr_patt_decode},
{"read_char", luacon_readchr},
{"draw_line", LuaConsoleGraphics::drawline},
{"draw_rect", LuaConsoleGraphics::drawrect},
{"fill_rect", LuaConsoleGraphics::fillrect},
{"clear_rect", LuaConsoleGraphics::clearrect},
{"draw_string", LuaConsoleGraphics::drawstr},
{"draw_str_v", LuaConsoleGraphics::drawstr_vertical},
{"clear", luacon_cls},
{"clear_ex", luacon_cls_ex},
{"set_blink_area", luacon_scrn_set_blink_a},
{"set_blink_decode", luacon_scrn_set_blink_dec},
{"clear_blink", luacon_scrn_clear_blink},
{"delay", luacon_wait},
{"rgb", luacolor_rgb},
{"cmd2rgb", luacolor_cmd2rgb},
{"photwl2rgb", luacolor_photwl2rgb},
{"icebp", luadbg_icebp},
{"ident", luaL_identity},
{"open_cmd", luadbg_open_cmd_shell},
{"restart", __lua_restart_prog},
{"pop_message", luacon_popmessage},
// {"new_thread", luacon_new_thread}, // needs pthread's pthread_create or windows' CreateThread or C++11's std::thread
{NULL, NULL}
};
#define ARGEXT(x) {#x,x},
#define ARGEXT_RGBI(x) ARGEXT(x##_RED) ARGEXT(x##_GREEN) ARGEXT(x##_BLUE) ARGEXT(x##_INTENSITY)
const static struct { const char* name; int value; } console_lua_api_ints[] = {
{"LUA_CONSOLE", 0}, {"LUA_WINDOW", 1}, {"EMPTY_WINDOW", -1},
ARGEXT(XRES) ARGEXT(YRES) ARGEXT(XCHRS) ARGEXT(YCHRS) ARGEXT(FLAG_RESET_STACK) ARGEXT(FLAG_READ_ATTR)
ARGEXT_RGBI(FOREGROUND) ARGEXT_RGBI(BACKGROUND) {NULL, 0},
{"WIDTH", CHRW}, {"HEIGHT", CHRH}, {"FLIP_X", FONT_FLIP_X}, {"FLIP_Y", FONT_FLIP_Y}, {"ROTATE", FONT_ROTATE},
{"BITS", FONT_NUM_CHAR_BITS}, {"MASK", (1 << FONT_NUM_CHAR_BITS) - 1}, {NULL, 0},
};
luaL_register(L, "console", console_lua_api);
SET_GLOBAL_ALIAS(L, "console", "con");
#ifdef __GNUC__
lua_pushliteral(L, MTOS(__GNUC__) "." MTOS(__GNUC_MINOR__));
lua_setfield(L, -2, "GNUC");
#endif
const static struct luaL_Reg console_additional_api [] = {
{"alloc", luacon_allocchr},
{"alloc_mult", luacon_alloc_multchr},
{"alloc_cont", luacon_allocchr_continuous},
{"free", luacon_freechr},
{"check", luacon_checkchr},
{"fill_rect", luacon_font_fill},
{"new_data", luacon_font_newdata},
{"get_data", luacon_font_getdata},
{"set_data", luacon_font_setdata},
{"to_data", luacon_to_font_data},
{"equal", luacon_font_is_equal},
{"band", luacon_font_bitw_and},
{"bor", luacon_font_bitw_or},
{"bnot", luacon_font_bitw_not},
{"bxor", luacon_font_bitw_xor},
{"xshift", luacon_font_shift_x},
{"yshift", luacon_font_shift_y},
{"flip", luacon_font_flip},
{"file", luacon_font_fileop},
{"character", NULL},
{"open", lua_alloc_subcon},
{"close", lua_free_subcon},
{"print", lua_write_subcon},
{"subconsole", NULL},
{"alloc", luacon_alloc_scrn},
{"free", luacon_free_scrn},
{"count", luacon_window_cnt},
{"capacity", luacon_window_cpct},
{"recalc", luacon_window_recalc},
{"switch", luacon_switch_window},
{"check", luacon_check_window},
{"file", luacon_window_fileop},
{"fullscreen", luacon_set_fullscreen},
{"next_window", luacon_next_window},
{"window", NULL},
{"suspend", luacon_altmenu_suspend},
{"resume", luacon_altmenu_resume},
{"altmenu", NULL},
{NULL, NULL}
};
const static char* console_api_aliases[] = {
"attribute", "attr", "character", "char", "character", "font", "subconsole", "subcon", "window", "win", "random", "rand",
"draw_string", "draw_str", NULL };
luaopen_con_attribute_api_(L);
luaopen_con_int32_api_(L); lua_setfield(L, -2, "int32");
luaL_register_ext(L, console_additional_api);
luarng_init_(L);
luaL_set_aliases(L, console_api_aliases);
luaopen_bit(L);
luacon_extend_str_api(L);
lua_settop(L, 0); // 清理 Lua 堆栈
int first_tick = SDL_GetTicks();
HANDLE sync_evt = CreateEvent(NULL, FALSE, FALSE, NULL);
luaL_custom_struct_0(st0) luacon_struct_0 = {L, &ScriptThreadHandle, &input_script_flag, sync_evt, 0};
HANDLE _th = GetCurrentThread(); // 线程伪句柄, 通常是 -2
HANDLE _ph = GetCurrentProcess(); // 进程伪句柄, 通常是 -1
DuplicateHandle(_ph, _th, _ph, &MainThreadHandle, 0, FALSE, DUPLICATE_SAME_ACCESS);
SetThreadPriority(_th, 1);
__luacon_panic_throw_bufs[(intptr_t)L] = (intptr_t)malloc(sizeof(jmp_buf));
ScriptThreadHandle.h = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)lua_process, &luacon_struct_0, CREATE_SUSPENDED, &(luacon_struct_0.sync_tid));
if (!ScriptThreadHandle.h)
{
exit_status = 1;
goto brk_1;
}
luacon_thread_handles.push_back((int*)&MainThreadHandle);
luacon_thread_handles.push_back((int*)&ScriptThreadHandle.h);
lua_getglobal(L, "console");
lua_newtable(L); // 普通表
lua_newtable(L); // 元表
SET_CFUNCTION(L, "__newindex", luacon_writeTableError);
SET_CFUNCTION(L, "__index", __luacon_read_handles);
lua_setmetatable(L, -2);
lua_setfield(L, -2, "handles"); // 加载句柄列表
lua_pushstring(L, "https://gitee.com/git123hub/luajit-test");
lua_setfield(L, -2, "SOURCE_CODE");
{
int i = luaL_va_setfield_ints(L, console_lua_api_ints);
lua_getfield(L, -1, "character");
luaL_va_setfield_ints(L, &console_lua_api_ints[i]);
}
lua_pop(L, 2); // 清理 Lua 堆栈
for (i = 0; i < LUA_SUBSTATES_COUNT; i++)
luacon_substates[i] = NULL;
{
char* filename_ptr = NULL;
for (i = 1; i < argc; i++)
{
if (argv[i][0] == '-')
read_cmd_arg(L, argv[i] + 1, &fullscreened, &altflags, &i, argc, argv);
else if (filename_ptr == NULL)
filename_ptr = argv[i];
}
ResumeThread(ScriptThreadHandle.h);
bool entered = false;
if (filename_ptr)
{
altflags &= ~ALT_ECHO_INPUT;
input_script_flag = false;
lua_proc_push_func(L, filename_ptr, sync_evt);
do {
is_quit = sdl_poll(&entered);
entered = false;
SwitchToThread();
__luacon_render_process (&first_tick, vid);
} while (!is_quit);
}
else
{
std::string lastCode = "";
do {
is_quit = sdl_poll(&entered);
if (entered)
{
entered = false, input_chars = 0, input_pos = 0;
lua_proc_push_func(L, chr_buffer, sync_evt);
}
SwitchToThread();
__luacon_render_process (&first_tick, vid);
} while (!is_quit);
}
if (altflags & ALT_ERR_RUN2) {
gfx_index = 0, lua_cursor = 0, console_blue_screen(L, text_buf);
for (;;)
{
SDL_Event event;
while (SDL_PollEvent(&event)) if (event.type == SDL_QUIT) goto brk_1;
__luacon_render_process(&first_tick, vid);
}
}
}
brk_1:
luaevent_cleanup_handles(L);
free(chr_buffer);
free(chr_buffer2);
free(ascii_font_ptr);
free(sdl_blinking_flags_0);
free(luacon_mask_table_0);
if (altflags & ALT_RESTART_PROG)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
memset(&si, 0, sizeof(si));
memset(&pi, 0, sizeof(pi));
CreateProcess(NULL, GetCommandLine(), NULL, NULL, false, 0, NULL, NULL, &si, &pi);
}
return exit_status;
}

评论 ( 0 )

你可以在登录后,发表评论