开源中国 2018 年度最后一场技术盛会邀你来约~错过就要等明年啦!点此立即预约

git123hub / luajit-testC/C++

Watch 1 Star 0 Fork 1
加入码云
与超过 300 万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
暂无描述 展开 收起

luaconsole_SDL.bat 31.27 KB
一键复制 编辑 Web IDE 原始数据 按行查看 历史
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205
:: 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 -march=i686 -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"
#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, luacon_tls_idx;
#ifdef __GNUC__
__thread jmp_buf * luacon_tls_panic;
#endif
// 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(1)))
int __luacon_process_pcall (lua_State * L) __asm__(".luacon_process_pcall");
__attribute__((regparm(3)))
void __luacon_swap64_asm (void*, void*, void*) __asm__(".luacon_swap64");
__attribute__((noinline, regparm(1), force_align_arg_pointer))
int __luacon_pcall_multret_0 (lua_State * L) __asm__(".luacon_pcall_multret.0");
int __luacon_pcall_resetstkoflw (void) __asm__(".luacon_pcall_resetstkoflw");
int __luacon_pcall_multret_0 (lua_State * L)
{
return lua_pcall(L, 0, LUA_MULTRET, 0);
}
int __luacon_pcall_resetstkoflw (void)
{
::EnterCriticalSection(&luacon_critlib_lock_0);
static bool init = false;
static FARPROC proc = (FARPROC)NULL;
int (*f)(void);
if (!init)
{
HMODULE m = ::LoadLibrary("msvcrt.dll");
if (m)
proc = GetProcAddress(m, "_resetstkoflw");
init = true;
}
(FARPROC&)f = proc;
::LeaveCriticalSection(&luacon_critlib_lock_0);
if (f != NULL)
return f();
return 0;
}
#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;
jmp_buf panicbuf;
memset(&panicbuf, 0, sizeof(jmp_buf)); // clears signature
#ifdef __GNUC__
luacon_tls_panic = &panicbuf;
#else
if (!TlsSetValue(luacon_tls_idx, &panicbuf))
abort();
#endif
if (setjmp(panicbuf))
{
#ifdef __GNUC__
__sync_fetch_and_or(&altflags, ALT_ERR_RUN2);
#else
EnterCriticalSection(&luacon_critical_0);
altflags |= ALT_ERR_RUN2;
LeaveCriticalSection(&luacon_critical_0);
#endif
CloseHandle(st->sync);
return 0;
}
for (;;)
{
for (;;)
{
EnterCriticalSection(&luacon_critical_0);
if (!lua_proc_func_queue.empty())
break;
LeaveCriticalSection(&luacon_critical_0);
WaitForSingleObject(st->sync, INFINITE);
}
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)
{
void * buf;
#ifdef __GNUC__
buf = luacon_tls_panic;
#else
buf = TlsGetValue(luacon_tls_idx);
if (buf == NULL) // (::GetLastError() != ERROR_SUCCESS)
abort();
#endif
longjmp(*(jmp_buf*)buf, 1);
}
intptr_t luacon_stateRegTable[2 * REG_MAX_LUA_STATES];
int main (int argc, char** argv)
{
#ifndef __GNUC__
int tls_idx = TlsAlloc();
if (tls_idx == TLS_OUT_OF_INDEXES)
exit(1);
luacon_tls_idx = tls_idx;
#endif
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);
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 )

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

搜索帮助