mirror of
https://github.com/u0u0/Cocos2d-Lua-Community.git
synced 2026-05-13 18:44:51 +08:00
282 lines
7.9 KiB
C++
Executable File
282 lines
7.9 KiB
C++
Executable File
// Copyright 2016 KeNan Liu
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include "scripting/lua-bindings/manual/tolua_fix.h"
|
|
#include "scripting/lua-bindings/manual/CCLuaEngine.h"
|
|
#include "cocos/audio/RDAudio.h"
|
|
#include "lua_audio_manual.h"
|
|
|
|
#define RD_AUDIO_BUFFER "Rapid2D_CAudioBuffer"
|
|
#define RD_AUDIO_SOURCE "Rapid2D_CAudioPlayer"
|
|
|
|
typedef struct _RDAudioItem {
|
|
ALuint id;
|
|
bool deleted;
|
|
} RDAudioItem;
|
|
|
|
static void callback(int handler, ALuint bufferID)
|
|
{
|
|
lua_State * L = cocos2d::LuaEngine::getInstance()->getLuaStack()->getLuaState();
|
|
|
|
if (bufferID > 0) {
|
|
// create userdata
|
|
RDAudioItem *bufferItem = (RDAudioItem *)lua_newuserdata(L, sizeof(RDAudioItem));
|
|
bufferItem->id = bufferID;
|
|
bufferItem->deleted = false;
|
|
// set metatable
|
|
luaL_getmetatable(L, RD_AUDIO_BUFFER);
|
|
lua_setmetatable(L, -2);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
|
|
cocos2d::LuaEngine::getInstance()->getLuaStack()->executeFunctionByHandler(handler, 1);
|
|
toluafix_remove_function_by_refid(L, handler);
|
|
}
|
|
|
|
static int lnewBuffer(lua_State * L)
|
|
{
|
|
// FilePath
|
|
const char *path = lua_tostring(L, 1);
|
|
int handler = (toluafix_ref_function(L,2,0));
|
|
RDAudio::getInstance()->loadFileAsyn(path, handler, callback);
|
|
|
|
return 0;// number of return values
|
|
}
|
|
|
|
static int lnewSource(lua_State * L)
|
|
{
|
|
ALuint sourceID;
|
|
// clear old error code.
|
|
alGetError();
|
|
// grab a source ID from openAL
|
|
alGenSources(1, &sourceID);
|
|
// check the error code.
|
|
if (alGetError() != AL_NO_ERROR) {
|
|
cocos2d::log("Rapid2D_CAudio.newSource() fail");
|
|
return 0;
|
|
}
|
|
|
|
// create userdata
|
|
RDAudioItem *sourceItem = (RDAudioItem *)lua_newuserdata(L, sizeof(RDAudioItem));
|
|
sourceItem->id = sourceID;
|
|
sourceItem->deleted = false;
|
|
// set metatable
|
|
luaL_getmetatable(L, RD_AUDIO_SOURCE);
|
|
lua_setmetatable(L, -2);
|
|
return 1;// number of return values
|
|
}
|
|
|
|
static int lpause(lua_State * L)
|
|
{
|
|
RDAudio::getInstance()->pause();
|
|
return 0;
|
|
}
|
|
|
|
static int lresume(lua_State * L)
|
|
{
|
|
RDAudio::getInstance()->resume();
|
|
return 0;
|
|
}
|
|
|
|
/******************** for buffer metatable ********************/
|
|
static int lBufferGC(lua_State *L)
|
|
{
|
|
RDAudioItem *bufferItem = (RDAudioItem *)luaL_checkudata(L, 1, RD_AUDIO_BUFFER);
|
|
if (!bufferItem->deleted) {
|
|
alDeleteBuffers(1, &bufferItem->id);
|
|
bufferItem->deleted = true;
|
|
}
|
|
return 0;// number of return values
|
|
}
|
|
|
|
static const struct luaL_Reg meta_buffer [] = {
|
|
{"__gc", lBufferGC},
|
|
{NULL, NULL}
|
|
};
|
|
|
|
/******************** for source metatable ********************/
|
|
static int lSourceGC(lua_State *L)
|
|
{
|
|
RDAudioItem *sourceItem = (RDAudioItem *)luaL_checkudata(L, 1, RD_AUDIO_SOURCE);
|
|
if (!sourceItem->deleted) {
|
|
alSourceStop(sourceItem->id);
|
|
alSourcei(sourceItem->id, AL_BUFFER, 0);
|
|
alDeleteSources(1, &sourceItem->id);
|
|
sourceItem->deleted = true;
|
|
}
|
|
return 0;// number of return values
|
|
}
|
|
|
|
static int lSourcePlay2d(lua_State *L)
|
|
{
|
|
RDAudioItem *sourceItem = (RDAudioItem *)luaL_checkudata(L, 1, RD_AUDIO_SOURCE);
|
|
RDAudioItem *bufferItem = (RDAudioItem *)luaL_checkudata(L, 2, RD_AUDIO_BUFFER);
|
|
int isLoop = lua_toboolean(L, 3);
|
|
|
|
if (sourceItem->deleted || bufferItem->deleted) {
|
|
cocos2d::log("Rapid2D_CAudioPlayer.play2d() fail for deleted!");
|
|
return 0;
|
|
}
|
|
|
|
// attach the buffer to the source
|
|
alSourcei(sourceItem->id, AL_BUFFER, bufferItem->id);
|
|
// set loop sound
|
|
alSourcei(sourceItem->id, AL_LOOPING, isLoop);
|
|
alSourcePlay(sourceItem->id);
|
|
// clean error code
|
|
alGetError();
|
|
return 0;
|
|
}
|
|
|
|
static int lSourcePause(lua_State *L)
|
|
{
|
|
RDAudioItem *sourceItem = (RDAudioItem *)luaL_checkudata(L, 1, RD_AUDIO_SOURCE);
|
|
if (sourceItem->deleted) {
|
|
cocos2d::log("Rapid2D_CAudioPlayer.pause() fail for deleted!");
|
|
return 0;
|
|
}
|
|
alSourcePause(sourceItem->id);
|
|
return 0;
|
|
}
|
|
|
|
static int lSourceResume(lua_State *L)
|
|
{
|
|
RDAudioItem *sourceItem = (RDAudioItem *)luaL_checkudata(L, 1, RD_AUDIO_SOURCE);
|
|
if (sourceItem->deleted) {
|
|
cocos2d::log("Rapid2D_CAudioPlayer.resume() fail for deleted!");
|
|
return 0;
|
|
}
|
|
ALint stat;
|
|
alGetSourcei(sourceItem->id, AL_SOURCE_STATE, &stat);
|
|
if (stat == AL_PAUSED) { // only resume on pause state
|
|
alSourcePlay(sourceItem->id);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int lSourceStop(lua_State *L)
|
|
{
|
|
RDAudioItem *sourceItem = (RDAudioItem *)luaL_checkudata(L, 1, RD_AUDIO_SOURCE);
|
|
if (sourceItem->deleted) {
|
|
cocos2d::log("Rapid2D_CAudioPlayer.stop() fail for deleted!");
|
|
return 0;
|
|
}
|
|
alSourceStop(sourceItem->id);
|
|
// deattach buffer from the source
|
|
alSourcei(sourceItem->id, AL_BUFFER, 0);
|
|
return 0;
|
|
}
|
|
|
|
static int lSourceSetVolume(lua_State *L)
|
|
{
|
|
RDAudioItem *sourceItem = (RDAudioItem *)luaL_checkudata(L, 1, RD_AUDIO_SOURCE);
|
|
if (sourceItem->deleted) {
|
|
cocos2d::log("Rapid2D_CAudioPlayer.setVolume() fail for deleted!");
|
|
return 0;
|
|
}
|
|
|
|
lua_Number volume = lua_tonumber(L, 2);
|
|
if (volume < 0.0f) {
|
|
volume = 0.0f;
|
|
}
|
|
if (volume > 1.0f) {
|
|
volume = 1.0f;
|
|
}
|
|
alSourcef(sourceItem->id, AL_GAIN, volume);
|
|
return 0;
|
|
}
|
|
|
|
static int lSourceGetStat(lua_State *L)
|
|
{
|
|
RDAudioItem *sourceItem = (RDAudioItem *)luaL_checkudata(L, 1, RD_AUDIO_SOURCE);
|
|
if (sourceItem->deleted) {
|
|
cocos2d::log("Rapid2D_CAudioPlayer.getStat() fail for deleted!");
|
|
return 0;
|
|
}
|
|
|
|
ALint stat;
|
|
alGetSourcei(sourceItem->id, AL_SOURCE_STATE, &stat);
|
|
switch (stat) {
|
|
case AL_INITIAL:
|
|
lua_pushinteger(L, 1);
|
|
break;
|
|
case AL_PLAYING:
|
|
lua_pushinteger(L, 2);
|
|
break;
|
|
case AL_PAUSED:
|
|
lua_pushinteger(L, 3);
|
|
break;
|
|
case AL_STOPPED:
|
|
lua_pushinteger(L, 4);
|
|
break;
|
|
default:
|
|
cocos2d::log("Rapid2D_CAudioPlayer.getStat() failed!");
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static const struct luaL_Reg meta_source [] = {
|
|
{"__gc", lSourceGC},
|
|
{"play2d", lSourcePlay2d},
|
|
{"pause", lSourcePause},
|
|
{"resume", lSourceResume},
|
|
{"stop", lSourceStop},
|
|
{"setVolume", lSourceSetVolume},
|
|
{"getStat", lSourceGetStat},
|
|
{NULL, NULL}
|
|
};
|
|
|
|
static const struct luaL_Reg audio_funcs [] = {
|
|
{"newBuffer", lnewBuffer},
|
|
{"newSource", lnewSource},
|
|
{"pause", lpause},
|
|
{"resume", lresume},
|
|
{NULL, NULL}
|
|
};
|
|
|
|
TOLUA_API int register_audio_module(lua_State* L)
|
|
{
|
|
// init OpenAL
|
|
RDAudio::getInstance();
|
|
|
|
lua_getglobal(L, "_G");
|
|
if (lua_istable(L,-1))//stack:...,_G,
|
|
{
|
|
luaL_newmetatable(L, RD_AUDIO_BUFFER);
|
|
/* metatable.__index = metatable */
|
|
lua_pushvalue(L, -1); /* duplicates the metatable */
|
|
lua_setfield(L, -2, "__index");
|
|
/* add method to metatable */
|
|
luaL_setfuncs(L, meta_buffer, 0);
|
|
lua_pop(L, 1); /* pop new metatable */
|
|
|
|
luaL_newmetatable(L, RD_AUDIO_SOURCE);
|
|
/* metatable.__index = metatable */
|
|
lua_pushvalue(L, -1); /* duplicates the metatable */
|
|
lua_setfield(L, -2, "__index");
|
|
/* add method to metatable */
|
|
luaL_setfuncs(L, meta_source, 0);
|
|
lua_pop(L, 1); /* pop new metatable */
|
|
|
|
// binding userdata to new metatable
|
|
luaL_register(L,"Rapid2D_CAudio", audio_funcs);
|
|
lua_pop(L, 1); /* pop Rapid2D_CAudio */
|
|
}
|
|
lua_pop(L, 1);
|
|
|
|
return 1;
|
|
}
|