添加更多方法. 添加异步转换音乐文件到wav
初步建立了异步调用模型, 底层采用thread/复用等实现. 对lua层通过SDL Event队列操作.
This commit is contained in:
parent
38a9808460
commit
566a85f3db
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -3,6 +3,8 @@ Debug/
|
||||||
Release/
|
Release/
|
||||||
|
|
||||||
asserts/
|
asserts/
|
||||||
|
bin/
|
||||||
|
tmp/
|
||||||
|
|
||||||
*.sln
|
*.sln
|
||||||
*.vcxproj
|
*.vcxproj
|
||||||
|
|
328
LuaEngine.cpp
328
LuaEngine.cpp
|
@ -1,7 +1,9 @@
|
||||||
#include "LuaEngine.h"
|
#include "LuaEngine.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <cstdlib>
|
||||||
#include "SDL2/include/SDL.h"
|
#include "SDL2/include/SDL.h"
|
||||||
#include "SDL2/include/SDL_mixer.h"
|
#include "SDL2/include/SDL_mixer.h"
|
||||||
#include "SDL2/include/SDL_ttf.h"
|
#include "SDL2/include/SDL_ttf.h"
|
||||||
|
@ -9,6 +11,9 @@
|
||||||
#include "PlatAPI.h"
|
#include "PlatAPI.h"
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
// Global single-thread unprotected event callback id counter
|
||||||
|
int callback_counter = 1;
|
||||||
|
|
||||||
void check(lua_State* L, const vector<int>& typearr)
|
void check(lua_State* L, const vector<int>& typearr)
|
||||||
{
|
{
|
||||||
int sz = typearr.size();
|
int sz = typearr.size();
|
||||||
|
@ -21,6 +26,33 @@ void check(lua_State* L, const vector<int>& typearr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConvertMusicAsyncImpl(const string& filename, const string& targetname, int ticket)
|
||||||
|
{
|
||||||
|
string command = "bin\\ffmpeg.exe -y -loglevel error -hide_banner -i \""s + filename + "\" " + targetname;
|
||||||
|
system(command.c_str());
|
||||||
|
SDL_Event e;
|
||||||
|
e.type = SDL_USEREVENT;
|
||||||
|
e.user.code = 1002; // General zero ret callback.
|
||||||
|
e.user.data1 = new int(ticket);
|
||||||
|
e.user.data2 = nullptr;
|
||||||
|
SDL_PushEvent(&e);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ConvertMusicAsync(lua_State* L)
|
||||||
|
{
|
||||||
|
check(L, { LUA_TSTRING, LUA_TSTRING, LUA_TFUNCTION });
|
||||||
|
lua_pushfstring(L, "cb%d", callback_counter);
|
||||||
|
lua_pushvalue(L, 3);
|
||||||
|
lua_settable(L, LUA_REGISTRYINDEX);
|
||||||
|
string filename(lua_tostring(L, 1));
|
||||||
|
string targetname(lua_tostring(L, 2));
|
||||||
|
thread td(ConvertMusicAsyncImpl, filename, targetname, callback_counter);
|
||||||
|
td.detach();
|
||||||
|
lua_pushnumber(L, callback_counter);
|
||||||
|
callback_counter++;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
struct LuaTimerCallbackData
|
struct LuaTimerCallbackData
|
||||||
{
|
{
|
||||||
void* p;
|
void* p;
|
||||||
|
@ -38,6 +70,32 @@ Uint32 LuaTimerCallbackGate(Uint32 interval, void* param)
|
||||||
return ((LuaTimerCallbackData*)(param))->type ? interval : 0;
|
return ((LuaTimerCallbackData*)(param))->type ? interval : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GetMouseState(const char** output, Uint32 state)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
if (state & SDL_BUTTON_LMASK)
|
||||||
|
{
|
||||||
|
output[i++] = "left";
|
||||||
|
}
|
||||||
|
if (state & SDL_BUTTON_MMASK)
|
||||||
|
{
|
||||||
|
output[i++] = "middle";
|
||||||
|
}
|
||||||
|
if (state & SDL_BUTTON_RMASK)
|
||||||
|
{
|
||||||
|
output[i++] = "right";
|
||||||
|
}
|
||||||
|
if (state & SDL_BUTTON_X1MASK)
|
||||||
|
{
|
||||||
|
output[i++] = "x1";
|
||||||
|
}
|
||||||
|
if (state & SDL_BUTTON_X2MASK)
|
||||||
|
{
|
||||||
|
output[i++] = "x2";
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
#define setfn(L, cfunc, name) lua_pushcfunction(L, cfunc); lua_setfield(L, -2, name)
|
#define setfn(L, cfunc, name) lua_pushcfunction(L, cfunc); lua_setfield(L, -2, name)
|
||||||
|
|
||||||
struct Window
|
struct Window
|
||||||
|
@ -78,11 +136,61 @@ struct Window
|
||||||
{
|
{
|
||||||
case SDL_MOUSEBUTTONDOWN:
|
case SDL_MOUSEBUTTONDOWN:
|
||||||
{
|
{
|
||||||
if (lua_getfield(L, -1, "onclick") != LUA_TNIL)
|
if (lua_getfield(L, -1, "onmousedown") != LUA_TNIL)
|
||||||
{
|
{
|
||||||
lua_pushnumber(L, e.button.x);
|
lua_pushnumber(L, e.button.x);
|
||||||
lua_pushnumber(L, e.button.y);
|
lua_pushnumber(L, e.button.y);
|
||||||
lua_call(L, 2, LUA_MULTRET);
|
lua_pushnumber(L, e.button.button);
|
||||||
|
const char* arr[8];
|
||||||
|
int ret = GetMouseState(arr, e.button.state);
|
||||||
|
lua_newtable(L);
|
||||||
|
for (int i = 0; i < ret; i++)
|
||||||
|
{
|
||||||
|
lua_pushboolean(L, 1);
|
||||||
|
lua_setfield(L, -2, arr[i]);
|
||||||
|
}
|
||||||
|
lua_call(L, 4, LUA_MULTRET);
|
||||||
|
}
|
||||||
|
else lua_pop(L, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_MOUSEBUTTONUP:
|
||||||
|
{
|
||||||
|
if (lua_getfield(L, -1, "onmouseup") != LUA_TNIL)
|
||||||
|
{
|
||||||
|
lua_pushnumber(L, e.button.x);
|
||||||
|
lua_pushnumber(L, e.button.y);
|
||||||
|
lua_pushnumber(L, e.button.button);
|
||||||
|
const char* arr[8];
|
||||||
|
int ret = GetMouseState(arr, e.button.state);
|
||||||
|
lua_newtable(L);
|
||||||
|
for (int i = 0; i < ret; i++)
|
||||||
|
{
|
||||||
|
lua_pushboolean(L, 1);
|
||||||
|
lua_setfield(L, -2, arr[i]);
|
||||||
|
}
|
||||||
|
lua_call(L, 3, LUA_MULTRET);
|
||||||
|
}
|
||||||
|
else lua_pop(L, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_MOUSEMOTION:
|
||||||
|
{
|
||||||
|
if (lua_getfield(L, -1, "onmousemove") != LUA_TNIL)
|
||||||
|
{
|
||||||
|
lua_pushnumber(L, e.motion.x);
|
||||||
|
lua_pushnumber(L, e.motion.y);
|
||||||
|
lua_pushnumber(L, e.motion.xrel);
|
||||||
|
lua_pushnumber(L, e.motion.yrel);
|
||||||
|
const char* arr[8];
|
||||||
|
int ret = GetMouseState(arr, e.button.state);
|
||||||
|
lua_newtable(L);
|
||||||
|
for (int i = 0; i < ret; i++)
|
||||||
|
{
|
||||||
|
lua_pushboolean(L, 1);
|
||||||
|
lua_setfield(L, -2, arr[i]);
|
||||||
|
}
|
||||||
|
lua_call(L, 5, LUA_MULTRET);
|
||||||
}
|
}
|
||||||
else lua_pop(L, 1);
|
else lua_pop(L, 1);
|
||||||
break;
|
break;
|
||||||
|
@ -107,6 +215,16 @@ struct Window
|
||||||
else lua_pop(L, 1);
|
else lua_pop(L, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SDL_KEYUP:
|
||||||
|
{
|
||||||
|
if (lua_getfield(L, -1, "onkeyup") != LUA_TNIL)
|
||||||
|
{
|
||||||
|
lua_pushnumber(L, e.key.keysym.sym);
|
||||||
|
lua_call(L, 1, LUA_MULTRET);
|
||||||
|
}
|
||||||
|
else lua_pop(L, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case SDL_USEREVENT:
|
case SDL_USEREVENT:
|
||||||
{
|
{
|
||||||
switch (e.user.code)
|
switch (e.user.code)
|
||||||
|
@ -123,9 +241,22 @@ struct Window
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 1002:
|
||||||
|
{
|
||||||
|
// 全局回调, 异步操作无返回值
|
||||||
|
lua_pushfstring(L, "cb%d", *(int*)e.user.data1);
|
||||||
|
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||||
|
delete e.user.data1;
|
||||||
|
lua_call(L, 0, LUA_MULTRET);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
cout << e.type << endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,6 +293,42 @@ struct Window
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int setInterval(lua_State* L)
|
||||||
|
{
|
||||||
|
check(L, { LUA_TUSERDATA, LUA_TFUNCTION, LUA_TNUMBER }); // ms
|
||||||
|
Window* p = (Window*)lua_touserdata(L, 1);
|
||||||
|
|
||||||
|
LuaTimerCallbackData* pd = new LuaTimerCallbackData();
|
||||||
|
pd->p = p;
|
||||||
|
pd->type = 1;
|
||||||
|
pd->id = SDL_AddTimer(lua_tointeger(L, 3), LuaTimerCallbackGate, pd);
|
||||||
|
|
||||||
|
lua_pushlightuserdata(L, p);
|
||||||
|
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||||
|
lua_pushfstring(L, "tmcb%d", pd->id);
|
||||||
|
lua_pushvalue(L, 2);
|
||||||
|
lua_settable(L, -3);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int showWindow(lua_State* L)
|
||||||
|
{
|
||||||
|
check(L, { LUA_TUSERDATA });
|
||||||
|
Window* p = (Window*)lua_touserdata(L, 1);
|
||||||
|
SDL_ShowWindow(p->wnd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hideWindow(lua_State* L)
|
||||||
|
{
|
||||||
|
check(L, { LUA_TUSERDATA });
|
||||||
|
Window* p = (Window*)lua_touserdata(L, 1);
|
||||||
|
|
||||||
|
SDL_HideWindow(p->wnd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int create(lua_State* L)
|
static int create(lua_State* L)
|
||||||
{
|
{
|
||||||
check(L, { LUA_TSTRING, LUA_TNUMBER, LUA_TNUMBER });
|
check(L, { LUA_TSTRING, LUA_TNUMBER, LUA_TNUMBER });
|
||||||
|
@ -188,6 +355,9 @@ struct Window
|
||||||
setfn(L, set_event_handler, "on");
|
setfn(L, set_event_handler, "on");
|
||||||
setfn(L, start, "start");
|
setfn(L, start, "start");
|
||||||
setfn(L, setTimeout, "setTimeout");
|
setfn(L, setTimeout, "setTimeout");
|
||||||
|
setfn(L, setInterval, "setInterval");
|
||||||
|
setfn(L, showWindow, "show");
|
||||||
|
setfn(L, hideWindow, "hide");
|
||||||
|
|
||||||
// Binding
|
// Binding
|
||||||
lua_setfield(L, -2, "__index");
|
lua_setfield(L, -2, "__index");
|
||||||
|
@ -198,7 +368,7 @@ struct Window
|
||||||
lua_setmetatable(L, -2);
|
lua_setmetatable(L, -2);
|
||||||
|
|
||||||
// Internal logic
|
// Internal logic
|
||||||
p->wnd = SDL_CreateWindow(lua_tostring(L, 1), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, lua_tointeger(L, 2), lua_tointeger(L, 3), SDL_WINDOW_SHOWN);
|
p->wnd = SDL_CreateWindow(lua_tostring(L, 1), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, lua_tointeger(L, 2), lua_tointeger(L, 3), SDL_WINDOW_HIDDEN);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -406,8 +576,21 @@ struct Renderer
|
||||||
static int copy(lua_State* L)
|
static int copy(lua_State* L)
|
||||||
{
|
{
|
||||||
check(L, { LUA_TUSERDATA, LUA_TUSERDATA, LUA_TTABLE, LUA_TTABLE });
|
check(L, { LUA_TUSERDATA, LUA_TUSERDATA, LUA_TTABLE, LUA_TTABLE });
|
||||||
Renderer* p = (Renderer*)lua_touserdata(L, 1);
|
Renderer* r = (Renderer*)lua_touserdata(L, 1);
|
||||||
|
Texture* t = (Texture*)lua_touserdata(L, 2);
|
||||||
|
SDL_Rect src;
|
||||||
|
int ret = LuaRectPointToRect(L, 3, src);
|
||||||
|
if (ret <= 0)
|
||||||
|
{
|
||||||
|
luaL_error(L, "Bad argument #%d. Rect expected, got %s", 3, lua_typename(L, lua_type(L, 3)));
|
||||||
|
}
|
||||||
|
SDL_Rect dst;
|
||||||
|
ret = LuaRectPointToRect(L, 4, dst);
|
||||||
|
if (ret <= 0)
|
||||||
|
{
|
||||||
|
luaL_error(L, "Bad argument #%d. Rect expected, got %s", 4, lua_typename(L, lua_type(L, 4)));
|
||||||
|
}
|
||||||
|
SDL_RenderCopy(r->rnd, t->text, &src, &dst);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,6 +614,26 @@ struct Renderer
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int copyFill(lua_State* L)
|
||||||
|
{
|
||||||
|
check(L, { LUA_TUSERDATA, LUA_TUSERDATA, LUA_TTABLE });
|
||||||
|
Renderer* r = (Renderer*)lua_touserdata(L, 1);
|
||||||
|
Texture* t = (Texture*)lua_touserdata(L, 2);
|
||||||
|
SDL_Rect rect;
|
||||||
|
int ret = LuaRectPointToRect(L, 3, rect);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
luaL_error(L, "Bad argument #%d. Point or Rect expected, got %s", 3, lua_typename(L, lua_type(L, 3)));
|
||||||
|
}
|
||||||
|
if (ret == 1)
|
||||||
|
{
|
||||||
|
rect.w = t->w;
|
||||||
|
rect.h = t->h;
|
||||||
|
}
|
||||||
|
SDL_RenderCopy(r->rnd, t->text, &rect, NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int create(lua_State* L)
|
static int create(lua_State* L)
|
||||||
{
|
{
|
||||||
check(L, { LUA_TUSERDATA });
|
check(L, { LUA_TUSERDATA });
|
||||||
|
@ -602,6 +805,61 @@ struct Font
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Chunk
|
||||||
|
{
|
||||||
|
Mix_Chunk* chunk;
|
||||||
|
|
||||||
|
static int close(lua_State* L)
|
||||||
|
{
|
||||||
|
check(L, { LUA_TUSERDATA });
|
||||||
|
cout << "In Chunk::close" << endl;
|
||||||
|
|
||||||
|
Chunk* c = (Chunk*)lua_touserdata(L, 1);
|
||||||
|
if (c->chunk)
|
||||||
|
{
|
||||||
|
Mix_FreeChunk(c->chunk);
|
||||||
|
c->chunk = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int create(lua_State* L)
|
||||||
|
{
|
||||||
|
check(L, { LUA_TSTRING });
|
||||||
|
cout << "In Chunk::create" << endl;
|
||||||
|
|
||||||
|
Chunk* c = (Chunk*)lua_newuserdata(L, sizeof(Chunk));
|
||||||
|
lua_getfield(L, LUA_REGISTRYINDEX, "__chunk_mt");
|
||||||
|
if (lua_type(L, -1) == LUA_TNIL)
|
||||||
|
{
|
||||||
|
lua_pop(L, 1);
|
||||||
|
lua_newtable(L);
|
||||||
|
// GC
|
||||||
|
lua_pushcfunction(L, close);
|
||||||
|
lua_setfield(L, -2, "__gc");
|
||||||
|
|
||||||
|
// Fields
|
||||||
|
lua_newtable(L);
|
||||||
|
lua_pushstring(L, "chunk"); lua_setfield(L, -2, "type");
|
||||||
|
setfn(L, close, "close");
|
||||||
|
|
||||||
|
// Set __index of metatable.
|
||||||
|
lua_setfield(L, -2, "__index");
|
||||||
|
|
||||||
|
lua_setfield(L, LUA_REGISTRYINDEX, "__chunk_mt");
|
||||||
|
lua_getfield(L, LUA_REGISTRYINDEX, "__chunk_mt");
|
||||||
|
}
|
||||||
|
lua_setmetatable(L, -2);
|
||||||
|
|
||||||
|
const char* filename = lua_tostring(L, 1);
|
||||||
|
c->chunk = Mix_LoadWAV(filename);
|
||||||
|
cout << "Load chunk error: " << SDL_GetError() << endl;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct Music
|
struct Music
|
||||||
{
|
{
|
||||||
Mix_Music* music;
|
Mix_Music* music;
|
||||||
|
@ -675,6 +933,48 @@ struct MusicPlayer
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int resume(lua_State* L)
|
||||||
|
{
|
||||||
|
check(L, { LUA_TUSERDATA });
|
||||||
|
MusicPlayer* p = (MusicPlayer*)lua_touserdata(L, 1);
|
||||||
|
Mix_ResumeMusic();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pause(lua_State* L)
|
||||||
|
{
|
||||||
|
check(L, { LUA_TUSERDATA });
|
||||||
|
MusicPlayer* p = (MusicPlayer*)lua_touserdata(L, 1);
|
||||||
|
Mix_PauseMusic();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fadeIn(lua_State* L)
|
||||||
|
{
|
||||||
|
check(L, { LUA_TUSERDATA, LUA_TUSERDATA , LUA_TNUMBER });
|
||||||
|
MusicPlayer* p = (MusicPlayer*)lua_touserdata(L, 1);
|
||||||
|
Music* m = (Music*)lua_touserdata(L, 2);
|
||||||
|
cout << "Fade in music ret: " << Mix_FadeInMusic(m->music, 1, lua_tointeger(L, 3)) << " " << SDL_GetError() << endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fadeOut(lua_State* L)
|
||||||
|
{
|
||||||
|
check(L, { LUA_TUSERDATA, LUA_TNUMBER });
|
||||||
|
MusicPlayer* p = (MusicPlayer*)lua_touserdata(L, 1);
|
||||||
|
cout << "Fade out music ret: " << Mix_FadeOutMusic(lua_tointeger(L, 2)) << " " << SDL_GetError() << endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int playChannel(lua_State* L)
|
||||||
|
{
|
||||||
|
check(L, { LUA_TUSERDATA, LUA_TUSERDATA, LUA_TNUMBER, LUA_TNUMBER});
|
||||||
|
MusicPlayer* p = (MusicPlayer*)lua_touserdata(L, 1);
|
||||||
|
Chunk* c = (Chunk*)lua_touserdata(L, 2);
|
||||||
|
cout << "Play channel ret: " << Mix_PlayChannel(lua_tointeger(L, 3), c->chunk, lua_tointeger(L, 4)) << " " << SDL_GetError() << endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int create(lua_State* L)
|
static int create(lua_State* L)
|
||||||
{
|
{
|
||||||
cout << "In MusicPlayer::create" << endl;
|
cout << "In MusicPlayer::create" << endl;
|
||||||
|
@ -694,6 +994,11 @@ struct MusicPlayer
|
||||||
lua_pushstring(L, "musicplayer"); lua_setfield(L, -2, "type");
|
lua_pushstring(L, "musicplayer"); lua_setfield(L, -2, "type");
|
||||||
setfn(L, close, "close");
|
setfn(L, close, "close");
|
||||||
setfn(L, play, "play");
|
setfn(L, play, "play");
|
||||||
|
setfn(L, pause, "pause");
|
||||||
|
setfn(L, resume, "resume");
|
||||||
|
setfn(L, fadeIn, "fadeIn");
|
||||||
|
setfn(L, fadeOut, "fadeOut");
|
||||||
|
setfn(L, playChannel, "playChannel");
|
||||||
|
|
||||||
// Set __index of metatable.
|
// Set __index of metatable.
|
||||||
lua_setfield(L, -2, "__index");
|
lua_setfield(L, -2, "__index");
|
||||||
|
@ -767,10 +1072,23 @@ int InitEngine(lua_State* L)
|
||||||
reg_in_lua(L, Window::create, "Window");
|
reg_in_lua(L, Window::create, "Window");
|
||||||
reg_in_lua(L, Renderer::create, "Renderer");
|
reg_in_lua(L, Renderer::create, "Renderer");
|
||||||
reg_in_lua(L, Font::create, "Font");
|
reg_in_lua(L, Font::create, "Font");
|
||||||
|
reg_in_lua(L, Chunk::create, "Chunk");
|
||||||
reg_in_lua(L, Music::create, "Music");
|
reg_in_lua(L, Music::create, "Music");
|
||||||
reg_in_lua(L, MusicPlayer::create, "MusicPlayer");
|
reg_in_lua(L, MusicPlayer::create, "MusicPlayer");
|
||||||
|
reg_in_lua(L, ConvertMusicAsync, "ConvertMusic");
|
||||||
|
|
||||||
LibFS::create(L); lua_setglobal(L, "fs");
|
LibFS::create(L); lua_setglobal(L, "fs");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int StopEngine()
|
||||||
|
{
|
||||||
|
Mix_CloseAudio();
|
||||||
|
Mix_Quit();
|
||||||
|
TTF_Quit();
|
||||||
|
IMG_Quit();
|
||||||
|
SDL_Quit();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -3,3 +3,4 @@
|
||||||
|
|
||||||
|
|
||||||
int InitEngine(lua_State* L);
|
int InitEngine(lua_State* L);
|
||||||
|
int StopEngine();
|
||||||
|
|
|
@ -5,11 +5,15 @@ using namespace std;
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
do {
|
||||||
LuaVM L;
|
LuaVM L;
|
||||||
InitEngine(L);
|
InitEngine(L);
|
||||||
|
cout << "<ENGINE> Started." << endl;
|
||||||
if (luaL_dofile(L, "code/game.lua"))
|
if (luaL_dofile(L, "code/game.lua"))
|
||||||
{
|
{
|
||||||
cout << lua_tostring(L, -1) << endl;
|
cout << lua_tostring(L, -1) << endl;
|
||||||
}
|
}
|
||||||
cout << "<ENGINE> Stopped." << endl;
|
cout << "<ENGINE> Stopped." << endl;
|
||||||
|
} while (0);
|
||||||
|
StopEngine();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,82 +1,64 @@
|
||||||
wnd = Window("Hello", 1024, 768)
|
local wnd = Window("Hello", 1024, 768)
|
||||||
rnd = Renderer(wnd)
|
local rnd = Renderer(wnd)
|
||||||
font = Font("asserts/msyh.ttf", 18)
|
local font = Font("asserts/msyh.ttf", 18)
|
||||||
musicPlayer = MusicPlayer()
|
local musicPlayer = MusicPlayer()
|
||||||
music = Music("asserts/mp3/bgm1.mp3")
|
local music = Music("asserts/mp3/bgm1.mp3")
|
||||||
|
|
||||||
function Point(x, y)
|
require("code/helper")
|
||||||
return {x=x,y=y,type="point"}
|
|
||||||
end
|
|
||||||
|
|
||||||
function Rect(x,y,w,h)
|
local all_bqb = fs.listdir("asserts/bqb_all")
|
||||||
return {x=x,y=y,w=w,h=h,type="rect"}
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
all_bqb = fs.listdir("asserts/bqb_all")
|
|
||||||
|
|
||||||
for i, info in ipairs(all_bqb) do
|
for i, info in ipairs(all_bqb) do
|
||||||
print (i, info.name, info.type, info.size)
|
print (i, info.name, info.type, info.size)
|
||||||
end
|
end
|
||||||
|
|
||||||
texture_track = {}
|
local texture_track = {}
|
||||||
setmetatable(texture_track, {
|
setmetatable(texture_track, {
|
||||||
__mode = "k"
|
__mode = "k"
|
||||||
})
|
})
|
||||||
|
|
||||||
texture_gc_limit_min = 20
|
|
||||||
texture_gc_limit = 20
|
|
||||||
texture_gc_activate = false
|
|
||||||
|
|
||||||
-- Gloabl gc timer
|
|
||||||
local function global_texture_cleaner()
|
|
||||||
local cnt = 0
|
|
||||||
for k in pairs(texture_track) do
|
|
||||||
cnt = cnt + 1
|
|
||||||
end
|
|
||||||
print ("Tracked texture: ", cnt, texture_gc_limit)
|
|
||||||
if cnt > texture_gc_limit then
|
|
||||||
collectgarbage("collect")
|
|
||||||
if texture_gc_activate then
|
|
||||||
texture_gc_limit = texture_gc_limit * 2
|
|
||||||
else
|
|
||||||
texture_gc_activate = true
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if not texture_gc_activate then
|
|
||||||
texture_gc_limit = (texture_gc_limit - 1) > texture_gc_limit_min and (texture_gc_limit - 1) or texture_gc_limit_min
|
|
||||||
else
|
|
||||||
texture_gc_activate = false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
wnd:setTimeout(global_texture_cleaner, 1000)
|
|
||||||
end
|
|
||||||
wnd:setTimeout(global_texture_cleaner, 1000)
|
|
||||||
|
|
||||||
-- Global garbage maker
|
|
||||||
local function global_garbage_maker()
|
|
||||||
texture_track[rnd:loadTexture("asserts/bqb_all/" .. all_bqb[math.random(#all_bqb)].name)] = true
|
|
||||||
|
|
||||||
wnd:setTimeout(global_garbage_maker, 1)
|
|
||||||
end
|
|
||||||
wnd:setTimeout(global_garbage_maker, 1)
|
|
||||||
|
|
||||||
wnd:setTimeout(function()
|
wnd:setTimeout(function()
|
||||||
print("Playing music")
|
print("Playing music")
|
||||||
musicPlayer:play(music)
|
musicPlayer:play(music)
|
||||||
print("Music started playing.")
|
print("Music started playing.")
|
||||||
|
wnd:show()
|
||||||
|
|
||||||
|
local filename = string.format("tmp/tmp_%d.wav", math.random(50))
|
||||||
|
ConvertMusic("asserts/mp3/bgm2.flac", filename, function()
|
||||||
|
print("Convert finished.")
|
||||||
|
wnd:setTimeout(function()
|
||||||
|
print("Start fade out", os.time())
|
||||||
|
musicPlayer:fadeOut(3000)
|
||||||
|
print("Finished fade out", os.time())
|
||||||
|
local c = Chunk(filename)
|
||||||
|
musicPlayer:playChannel(c, -1, 1)
|
||||||
|
end, 2000)
|
||||||
|
end)
|
||||||
|
|
||||||
|
--[[
|
||||||
|
for i=1, 10 do
|
||||||
|
local filename = string.format("tmp/tmp_%d.wav", math.random(50))
|
||||||
|
print ("ConvertTickets: ", ConvertMusic("asserts/mp3/bgm1.mp3", filename, function() print("Convert finished.", filename) end))
|
||||||
|
end
|
||||||
|
--]]
|
||||||
end, 3000)
|
end, 3000)
|
||||||
|
|
||||||
wnd:on('click', function(x, y)
|
wnd:on('mousedown', function(x, y)
|
||||||
print("Clicked", x, y)
|
print("Clicked", x, y)
|
||||||
local t = font:renderText(rnd, string.format("%.0f,%.0f", x, y), {r=255,g=255,b=255,a=0,type="color"})
|
local t = font:renderText(rnd, string.format("%.0f,%.0f", x, y), {r=255,g=255,b=255,a=0,type="color"})
|
||||||
texture_track[t] = true
|
texture_track[t] = true
|
||||||
rnd:copyTo(t, {x=x,y=y,type="point"})
|
rnd:copyTo(t, {x=x,y=y,type="point"})
|
||||||
rnd:update()
|
rnd:update()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
wnd:on('mousemove', function(x, y, xrel, yrel)
|
||||||
|
-- print("Mousemove", x, y, xrel, yrel)
|
||||||
|
end)
|
||||||
|
|
||||||
wnd:on('quit', function()
|
wnd:on('quit', function()
|
||||||
print("before quit")
|
print("before quit")
|
||||||
end)
|
end)
|
||||||
|
|
||||||
wnd:on('keydown', function(key)
|
wnd:on('keydown', function(key)
|
||||||
if key == string.byte('q') then
|
if key == string.byte('q') then
|
||||||
local current = collectgarbage("count")
|
local current = collectgarbage("count")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user