-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
396 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
std = "max" | ||
files['.luacheckrc'].global = false | ||
unused_args = false | ||
|
||
globals = { | ||
"sys", | ||
"go", | ||
"gui", | ||
"label", | ||
"render", | ||
"crash", | ||
"sprite", | ||
"sound", | ||
"tilemap", | ||
"spine", | ||
"particlefx", | ||
"physics", | ||
"factory", | ||
"collectionfactory", | ||
"iac", | ||
"msg", | ||
"vmath", | ||
"url", | ||
"http", | ||
"image", | ||
"json", | ||
"zlib", | ||
"iap", | ||
"push", | ||
"facebook", | ||
"hash", | ||
"hash_to_hex", | ||
"pprint", | ||
"init", | ||
"final", | ||
"update", | ||
"on_input", | ||
"on_message", | ||
"on_reload", | ||
"window", | ||
"unityads", | ||
"socket", | ||
"defreview", | ||
"resource", | ||
"buffer", | ||
"drawpixels" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
name: "DrawPixels" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,232 @@ | ||
// Extension lib defines | ||
#define LIB_NAME "DrawPixels" | ||
#define MODULE_NAME "drawpixels" | ||
|
||
#define DLIB_LOG_DOMAIN LIB_NAME | ||
|
||
#include <dmsdk/sdk.h> | ||
#include <math.h> | ||
|
||
struct BufferInfo | ||
{ | ||
dmBuffer::HBuffer buffer; | ||
int width; | ||
int height; | ||
int colors_count; | ||
}; | ||
|
||
BufferInfo buffer_info; | ||
|
||
static int xytoi(int x, int y, int w, int h, int bpp) { | ||
if (x < 0) x = 0; | ||
if (y < 0) y = 0; | ||
if (x >= w) x = w - 1; | ||
if (y >= h) y = h - 1; | ||
return (y * w * bpp) + (x * bpp); | ||
} | ||
|
||
static int lenght(int x1, int y1, int x2, int y2){ | ||
int a = x1-x2; | ||
int b = y1-y2; | ||
return sqrt(a*a + b*b); | ||
} | ||
|
||
static void read_and_validate_buffer_info(lua_State* L, int index) { | ||
luaL_checktype(L, index, LUA_TTABLE); | ||
lua_getfield(L, index, "buffer"); | ||
lua_getfield(L, index, "width"); | ||
lua_getfield(L, index, "height"); | ||
lua_getfield(L, index, "colors_count"); | ||
dmScript::LuaHBuffer *lua_buffer = dmScript::CheckBuffer(L, -4); | ||
buffer_info.buffer = lua_buffer->m_Buffer; | ||
|
||
if (!dmBuffer::IsBufferValid(buffer_info.buffer)) { | ||
luaL_error(L, "Buffer is invalid"); | ||
} | ||
|
||
buffer_info.width = lua_tointeger(L, -3); | ||
if (buffer_info.width == 0) { | ||
luaL_error(L, "'width' of the buffer should be an integer and > 0"); | ||
} | ||
|
||
buffer_info.height = lua_tointeger(L, -2); | ||
if (buffer_info.height == 0) { | ||
luaL_error(L, "'height' of the buffer should be an integer and > 0"); | ||
} | ||
|
||
buffer_info.colors_count = lua_tointeger(L, -1); | ||
if (buffer_info.colors_count == 0) { | ||
luaL_error(L, "'colors_count' of the buffer should be an integer and > 0"); | ||
} | ||
} | ||
|
||
static int draw_circle(lua_State* L) { | ||
int top = lua_gettop(L) + 4; | ||
|
||
read_and_validate_buffer_info(L, 1); | ||
uint32_t posx = luaL_checknumber(L, 2); | ||
uint32_t posy = luaL_checknumber(L, 3); | ||
uint32_t size = luaL_checknumber(L, 4); | ||
uint32_t r = luaL_checknumber(L, 5); | ||
uint32_t g = luaL_checknumber(L, 6); | ||
uint32_t b = luaL_checknumber(L, 7); | ||
uint32_t a = 0; | ||
if (lua_isnumber(L, 5) == 1) | ||
{ | ||
a = luaL_checknumber(L, 5); | ||
} | ||
|
||
uint8_t* bytes = 0; | ||
uint32_t src_size = 0; | ||
|
||
dmBuffer::Result result = dmBuffer::GetBytes(buffer_info.buffer, (void**)&bytes, &src_size); | ||
if (result != dmBuffer::RESULT_OK) { | ||
dmLogError("Unable to get bytes from source buffer"); | ||
return 0; | ||
} | ||
int newposx = 0; | ||
int newposy = 0; | ||
int half_size = size/2; | ||
for(int x = -half_size; x < half_size; x++) { | ||
for(int y = -half_size; y < half_size; y++) { | ||
newposx = x + posx; | ||
newposy = y + posy; | ||
if (lenght(newposx, newposy, posx, posy) < half_size) { | ||
int i = xytoi(newposx, newposy, buffer_info.width, buffer_info.height, buffer_info.colors_count); | ||
bytes[i] = r; | ||
bytes[i + 1] = g; | ||
bytes[i + 2] = b; | ||
if (buffer_info.colors_count == 4) { | ||
bytes[i + 3] = a; | ||
} | ||
} | ||
} | ||
} | ||
|
||
assert(top == lua_gettop(L)); | ||
return 0; | ||
} | ||
|
||
static int fill_texture(lua_State* L) { | ||
int top = lua_gettop(L) + 4; | ||
|
||
read_and_validate_buffer_info(L, 1); | ||
uint32_t r = luaL_checknumber(L, 2); | ||
uint32_t g = luaL_checknumber(L, 3); | ||
uint32_t b = luaL_checknumber(L, 4); | ||
uint32_t a = 0; | ||
if (lua_isnumber(L, 5) == 1) | ||
{ | ||
a = luaL_checknumber(L, 5); | ||
} | ||
|
||
uint8_t* bytes = 0; | ||
uint32_t src_size = 0; | ||
|
||
dmBuffer::Result result = dmBuffer::GetBytes(buffer_info.buffer, (void**)&bytes, &src_size); | ||
if (result != dmBuffer::RESULT_OK) { | ||
dmLogError("Unable to get bytes from source buffer"); | ||
return 0; | ||
} | ||
for(int i = 0; i < src_size; i += buffer_info.colors_count) { | ||
bytes[i] = r; | ||
bytes[i + 1] = g; | ||
bytes[i + 2] = b; | ||
if (buffer_info.colors_count == 4) { | ||
bytes[i + 3] = a; | ||
} | ||
} | ||
|
||
assert(top == lua_gettop(L)); | ||
return 0; | ||
} | ||
|
||
static int draw_rect(lua_State* L) { | ||
int top = lua_gettop(L) + 4; | ||
|
||
read_and_validate_buffer_info(L, 1); | ||
uint32_t posx = luaL_checknumber(L, 2); | ||
uint32_t posy = luaL_checknumber(L, 3); | ||
uint32_t sizex = luaL_checknumber(L, 4); | ||
uint32_t sizey = luaL_checknumber(L, 5); | ||
uint32_t r = luaL_checknumber(L, 6); | ||
uint32_t g = luaL_checknumber(L, 7); | ||
uint32_t b = luaL_checknumber(L, 8); | ||
uint32_t a = 0; | ||
if (lua_isnumber(L, 5) == 1) | ||
{ | ||
a = luaL_checknumber(L, 5); | ||
} | ||
|
||
uint8_t* bytes = 0; | ||
uint32_t src_size = 0; | ||
|
||
dmBuffer::Result result = dmBuffer::GetBytes(buffer_info.buffer, (void**)&bytes, &src_size); | ||
if (result != dmBuffer::RESULT_OK) { | ||
dmLogError("Unable to get bytes from source buffer"); | ||
return 0; | ||
} | ||
|
||
int half_size_x = sizex/2; | ||
int half_size_y = sizey/2; | ||
int newposx = 0; | ||
int newposy = 0; | ||
for(int x = -half_size_x; x < half_size_x; x++) { | ||
for(int y = -half_size_y; y < half_size_y; y++) { | ||
newposx = x + posx; | ||
newposy = y + posy; | ||
int i = xytoi(newposx, newposy, buffer_info.width, buffer_info.height, buffer_info.colors_count); | ||
bytes[i] = r; | ||
bytes[i + 1] = g; | ||
bytes[i + 2] = b; | ||
if (buffer_info.colors_count == 4) { | ||
bytes[i + 3] = a; | ||
} | ||
} | ||
} | ||
|
||
assert(top == lua_gettop(L)); | ||
return 0; | ||
} | ||
|
||
// Functions exposed to Lua | ||
static const luaL_reg Module_methods[] = { | ||
{"circle", draw_circle}, | ||
{"fill", fill_texture}, | ||
{"rect", draw_rect}, | ||
{0, 0} | ||
}; | ||
|
||
static void LuaInit(lua_State* L) { | ||
int top = lua_gettop(L); | ||
// Register lua names | ||
luaL_register(L, MODULE_NAME, Module_methods); | ||
lua_pop(L, 1); | ||
assert(top == lua_gettop(L)); | ||
} | ||
|
||
dmExtension::Result AppInitializeImpExtension(dmExtension::AppParams* params) { | ||
return dmExtension::RESULT_OK; | ||
} | ||
|
||
dmExtension::Result InitializeImpExtension(dmExtension::Params* params) { | ||
// Init Lua | ||
LuaInit(params->m_L); | ||
printf("Registered %s Extension\n", MODULE_NAME); | ||
return dmExtension::RESULT_OK; | ||
} | ||
|
||
dmExtension::Result AppFinalizeImpExtension(dmExtension::AppParams* params) { | ||
return dmExtension::RESULT_OK; | ||
} | ||
|
||
dmExtension::Result FinalizeImpExtension(dmExtension::Params* params) { | ||
return dmExtension::RESULT_OK; | ||
} | ||
|
||
|
||
// Defold SDK uses a macro for setting up extension entry points: | ||
// | ||
// DM_DECLARE_EXTENSION(symbol, name, app_init, app_final, init, update, on_event, final) | ||
|
||
DM_DECLARE_EXTENSION(DrawPixels, LIB_NAME, AppInitializeImpExtension, AppFinalizeImpExtension, InitializeImpExtension, 0, 0, FinalizeImpExtension) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
function init(self) | ||
msg.post(".", "acquire_input_focus") | ||
|
||
-- size of texture when scaled to nearest power of two | ||
local width = 512 | ||
local height = 1024 | ||
|
||
local our_buffer = buffer.create(width * height, {{name = hash("rgba"), type = buffer.VALUE_TYPE_UINT8, count = 4}}) | ||
|
||
self.buffer_info = { | ||
buffer = our_buffer, | ||
width = width, | ||
height = height, | ||
colors_count = 4 --- 3 for rgb, 4 for rgba | ||
} | ||
|
||
drawpixels.fill(self.buffer_info, 128, 128, 128) | ||
self.dirty = true | ||
|
||
-- drawing params | ||
self.prev_pos = vmath.vector3() | ||
self.resource_path = go.get("#sprite", "texture0") | ||
self.header = { | ||
width = width, | ||
height = height, | ||
type = resource.TEXTURE_TYPE_2D, | ||
format = resource.TEXTURE_FORMAT_RGBA, | ||
num_mip_maps = 1 | ||
} | ||
end | ||
|
||
function update(self, dt) | ||
-- update texture if it's dirty (ie we've drawn to it) | ||
if self.dirty then | ||
resource.set_texture(self.resource_path, self.header, self.buffer_info.buffer) | ||
self.dirty = false | ||
end | ||
end | ||
|
||
function on_input(self, action_id, action) | ||
if action_id == hash("touch") then | ||
local pos = vmath.vector3(action.x, action.y, 0) | ||
if action.pressed then | ||
self.drawing = true | ||
self.touch_pos = pos | ||
elseif action.released then | ||
self.drawing = false | ||
end | ||
if self.drawing then | ||
-- calculate the length and direction from the previous touch | ||
-- position to the current position | ||
local length = math.ceil(vmath.length(self.touch_pos - pos)) | ||
local dir = vmath.normalize(self.touch_pos - pos) | ||
if length == 0 then | ||
length = 1 | ||
dir = vmath.vector3(0) | ||
end | ||
if self.prev_pos == pos then | ||
return false | ||
end | ||
self.prev_pos = self.touch_pos | ||
-- use current tool from the previous touch position to | ||
-- the current touch position0 | ||
while length > 0 do | ||
drawpixels.rect(self.buffer_info, self.touch_pos.x, self.touch_pos.y, 40, 40, 255, 255, 255, 255) | ||
-- drawpixels.circle(self.buffer_info, self.touch_pos.x, self.touch_pos.y, 120, 255, 255, 255, 255) | ||
self.dirty = true | ||
self.touch_pos = self.touch_pos - dir | ||
length = length - 1 | ||
end | ||
end | ||
end | ||
end | ||
|
||
function on_reload(self) | ||
-- Add reload-handling code here | ||
-- Remove this function if not needed | ||
end |
Oops, something went wrong.