1 #include "lua/internal.hpp"
2 #include "library/framebuffer.hpp"
3 #include "lua/bitmap.hpp"
6 lua_bitmap::lua_bitmap(uint32_t w
, uint32_t h
)
10 pixels
.resize(width
* height
);
11 memset(&pixels
[0], 0, width
* height
);
14 lua_dbitmap::lua_dbitmap(uint32_t w
, uint32_t h
)
18 pixels
.resize(width
* height
);
21 lua_palette::lua_palette()
23 palette_mutex
= &mutex::aquire();
26 lua_palette::~lua_palette()
33 struct render_object_bitmap
: public render_object
35 render_object_bitmap(int32_t _x
, int32_t _y
, lua_obj_pin
<lua_bitmap
>* _bitmap
,
36 lua_obj_pin
<lua_palette
>* _palette
) throw()
45 render_object_bitmap(int32_t _x
, int32_t _y
, lua_obj_pin
<lua_dbitmap
>* _bitmap
) throw()
54 ~render_object_bitmap() throw()
61 template<bool T
> void composite_op(struct framebuffer
<T
>& scr
) throw()
64 p
->object()->palette_mutex
->lock();
65 uint32_t originx
= scr
.get_origin_x();
66 uint32_t originy
= scr
.get_origin_y();
69 premultiplied_color
* palette
;
71 palette
= &p
->object()->colors
[0];
72 for(auto& c
: p
->object()->colors
)
74 pallim
= p
->object()->colors
.size();
75 w
= b
->object()->width
;
76 h
= b
->object()->height
;
78 for(auto& c
: b2
->object()->pixels
)
80 w
= b2
->object()->width
;
81 h
= b2
->object()->height
;
88 clip_range(originx
, scr
.get_width(), x
, xmin
, xmax
);
89 clip_range(originy
, scr
.get_height(), y
, ymin
, ymax
);
90 for(int32_t r
= ymin
; r
< ymax
; r
++) {
91 typename framebuffer
<T
>::element_t
* rptr
= scr
.rowptr(y
+ r
+ originy
);
92 size_t eptr
= x
+ xmin
+ originx
;
94 for(int32_t c
= xmin
; c
< xmax
; c
++, eptr
++) {
95 uint16_t i
= b
->object()->pixels
[r
* b
->object()->width
+ c
];
97 palette
[i
].apply(rptr
[eptr
]);
100 for(int32_t c
= xmin
; c
< xmax
; c
++, eptr
++)
101 b2
->object()->pixels
[r
* b2
->object()->width
+ c
].apply(rptr
[eptr
]);
104 p
->object()->palette_mutex
->unlock();
106 void operator()(struct framebuffer
<false>& x
) throw() { composite_op(x
); }
107 void operator()(struct framebuffer
<true>& x
) throw() { composite_op(x
); }
111 lua_obj_pin
<lua_bitmap
>* b
;
112 lua_obj_pin
<lua_dbitmap
>* b2
;
113 lua_obj_pin
<lua_palette
>* p
;
116 function_ptr_luafun
gui_bitmap(LS
, "gui.bitmap_draw", [](lua_state
& L
, const std::string
& fname
) -> int {
119 int32_t x
= L
.get_numeric_argument
<int32_t>(1, fname
.c_str());
120 int32_t y
= L
.get_numeric_argument
<int32_t>(2, fname
.c_str());
121 if(lua_class
<lua_bitmap
>::is(L
, 3)) {
122 lua_class
<lua_bitmap
>::get(L
, 3, fname
.c_str());
123 lua_class
<lua_palette
>::get(L
, 4, fname
.c_str());
124 auto b
= lua_class
<lua_bitmap
>::pin(L
, 3, fname
.c_str());
125 auto p
= lua_class
<lua_palette
>::pin(L
, 4, fname
.c_str());
126 lua_render_ctx
->queue
->create_add
<render_object_bitmap
>(x
, y
, b
, p
);
127 } else if(lua_class
<lua_dbitmap
>::is(L
, 3)) {
128 lua_class
<lua_dbitmap
>::get(L
, 3, fname
.c_str());
129 auto b
= lua_class
<lua_dbitmap
>::pin(L
, 3, fname
.c_str());
130 lua_render_ctx
->queue
->create_add
<render_object_bitmap
>(x
, y
, b
);
132 L
.pushstring("Expected BITMAP or DBITMAP as argument 3 for gui.bitmap_draw.");
138 function_ptr_luafun
gui_cpalette(LS
, "gui.palette_new", [](lua_state
& L
, const std::string
& fname
) -> int {
139 lua_class
<lua_palette
>::create(L
);
143 function_ptr_luafun
gui_cbitmap(LS
, "gui.bitmap_new", [](lua_state
& L
, const std::string
& fname
) -> int {
144 uint32_t w
= L
.get_numeric_argument
<uint32_t>(1, fname
.c_str());
145 uint32_t h
= L
.get_numeric_argument
<uint32_t>(2, fname
.c_str());
146 bool d
= L
.get_bool(3, fname
.c_str());
149 L
.get_numeric_argument
<int64_t>(4, c
, fname
.c_str());
150 lua_dbitmap
* b
= lua_class
<lua_dbitmap
>::create(L
, w
, h
);
151 for(size_t i
= 0; i
< b
->width
* b
->height
; i
++)
152 b
->pixels
[i
] = premultiplied_color(c
);
155 L
.get_numeric_argument
<uint16_t>(4, c
, fname
.c_str());
156 lua_bitmap
* b
= lua_class
<lua_bitmap
>::create(L
, w
, h
);
157 for(size_t i
= 0; i
< b
->width
* b
->height
; i
++)
163 function_ptr_luafun
gui_epalette(LS
, "gui.palette_set", [](lua_state
& L
, const std::string
& fname
) -> int {
164 lua_palette
* p
= lua_class
<lua_palette
>::get(L
, 1, fname
.c_str());
165 uint16_t c
= L
.get_numeric_argument
<uint16_t>(2, fname
.c_str());
166 int64_t nval
= L
.get_numeric_argument
<int64_t>(3, fname
.c_str());
167 premultiplied_color
nc(nval
);
168 //The mutex lock protects only the internals of colors array.
169 if(p
->colors
.size() <= c
) {
170 p
->palette_mutex
->lock();
171 p
->colors
.resize(static_cast<uint32_t>(c
) + 1);
172 p
->palette_mutex
->unlock();
178 function_ptr_luafun
pset_bitmap(LS
, "gui.bitmap_pset", [](lua_state
& L
, const std::string
& fname
) -> int {
179 uint32_t x
= L
.get_numeric_argument
<uint32_t>(2, fname
.c_str());
180 uint32_t y
= L
.get_numeric_argument
<uint32_t>(3, fname
.c_str());
181 if(lua_class
<lua_bitmap
>::is(L
, 1)) {
182 lua_bitmap
* b
= lua_class
<lua_bitmap
>::get(L
, 1, fname
.c_str());
183 uint16_t c
= L
.get_numeric_argument
<uint16_t>(4, fname
.c_str());
184 if(x
>= b
->width
|| y
>= b
->height
)
186 b
->pixels
[y
* b
->width
+ x
] = c
;
187 } else if(lua_class
<lua_dbitmap
>::is(L
, 1)) {
188 lua_dbitmap
* b
= lua_class
<lua_dbitmap
>::get(L
, 1, fname
.c_str());
189 int64_t c
= L
.get_numeric_argument
<int64_t>(4, fname
.c_str());
190 if(x
>= b
->width
|| y
>= b
->height
)
192 b
->pixels
[y
* b
->width
+ x
] = premultiplied_color(c
);
194 L
.pushstring("Expected BITMAP or DBITMAP as argument 1 for gui.bitmap_pset.");
200 function_ptr_luafun
size_bitmap(LS
, "gui.bitmap_size", [](lua_state
& L
, const std::string
& fname
) -> int {
201 if(lua_class
<lua_bitmap
>::is(L
, 1)) {
202 lua_bitmap
* b
= lua_class
<lua_bitmap
>::get(L
, 1, fname
.c_str());
203 L
.pushnumber(b
->width
);
204 L
.pushnumber(b
->height
);
205 } else if(lua_class
<lua_dbitmap
>::is(L
, 1)) {
206 lua_dbitmap
* b
= lua_class
<lua_dbitmap
>::get(L
, 1, fname
.c_str());
207 L
.pushnumber(b
->width
);
208 L
.pushnumber(b
->height
);
210 L
.pushstring("Expected BITMAP or DBITMAP as argument 1 for gui.bitmap_size.");
216 function_ptr_luafun
blit_bitmap(LS
, "gui.bitmap_blit", [](lua_state
& L
, const std::string
& fname
) -> int {
217 uint32_t dx
= L
.get_numeric_argument
<uint32_t>(2, fname
.c_str());
218 uint32_t dy
= L
.get_numeric_argument
<uint32_t>(3, fname
.c_str());
219 uint32_t sx
= L
.get_numeric_argument
<uint32_t>(5, fname
.c_str());
220 uint32_t sy
= L
.get_numeric_argument
<uint32_t>(6, fname
.c_str());
221 uint32_t w
= L
.get_numeric_argument
<uint32_t>(7, fname
.c_str());
222 uint32_t h
= L
.get_numeric_argument
<uint32_t>(8, fname
.c_str());
223 int64_t ck
= 0x100000000ULL
;
224 L
.get_numeric_argument
<int64_t>(9, ck
, fname
.c_str());
226 premultiplied_color
pck(ck
);
227 uint32_t ckorig
= pck
.orig
;
228 uint16_t ckoriga
= pck
.origa
;
229 if(ck
== 0x100000000ULL
)
231 if(lua_class
<lua_bitmap
>::is(L
, 1) && lua_class
<lua_bitmap
>::is(L
, 4)) {
232 lua_bitmap
* db
= lua_class
<lua_bitmap
>::get(L
, 1, fname
.c_str());
233 lua_bitmap
* sb
= lua_class
<lua_bitmap
>::get(L
, 4, fname
.c_str());
234 while((dx
+ w
> db
->width
|| sx
+ w
> sb
->width
) && w
> 0)
236 while((dy
+ h
> db
->height
|| sy
+ h
> sb
->height
) && h
> 0)
238 size_t sidx
= sy
* sb
->width
+ sx
;
239 size_t didx
= dy
* db
->width
+ dx
;
240 size_t srskip
= sb
->width
- w
;
241 size_t drskip
= db
->width
- w
;
242 for(uint32_t j
= 0; j
< h
; j
++) {
243 for(uint32_t i
= 0; i
< w
; i
++) {
244 uint16_t pix
= sb
->pixels
[sidx
];
245 if(pix
!= ck
) //No need to check nck, as that value is out of range.
246 db
->pixels
[didx
] = pix
;
253 } else if(lua_class
<lua_dbitmap
>::is(L
, 1) && lua_class
<lua_dbitmap
>::is(L
, 1)) {
254 lua_dbitmap
* db
= lua_class
<lua_dbitmap
>::get(L
, 1, fname
.c_str());
255 lua_dbitmap
* sb
= lua_class
<lua_dbitmap
>::get(L
, 4, fname
.c_str());
256 while((dx
+ w
> db
->width
|| sx
+ w
> sb
->width
) && w
> 0)
258 while((dy
+ h
> db
->height
|| sy
+ h
> sb
->height
) && h
> 0)
260 size_t sidx
= sy
* sb
->width
+ sx
;
261 size_t didx
= dy
* db
->width
+ dx
;
262 size_t srskip
= sb
->width
- w
;
263 size_t drskip
= db
->width
- w
;
264 for(uint32_t j
= 0; j
< h
; j
++) {
265 for(uint32_t i
= 0; i
< w
; i
++) {
266 premultiplied_color pix
= sb
->pixels
[sidx
];
267 if(pix
.orig
!= ckorig
|| pix
.origa
!= ckoriga
|| nck
)
268 db
->pixels
[didx
] = pix
;
276 L
.pushstring("Expected BITMAP or DBITMAP as arguments 1&4 for gui.bitmap_pset.");
282 function_ptr_luafun
gui_loadbitmap(LS
, "gui.bitmap_load", [](lua_state
& L
, const std::string
& fname
) -> int {
283 std::string name
= L
.get_string(1, fname
.c_str());
285 auto bitmap
= lua_loaded_bitmap::load(name
);
287 lua_dbitmap
* b
= lua_class
<lua_dbitmap
>::create(L
, bitmap
.w
, bitmap
.h
);
288 for(size_t i
= 0; i
< bitmap
.w
* bitmap
.h
; i
++)
289 b
->pixels
[i
] = premultiplied_color(bitmap
.bitmap
[i
]);
292 lua_bitmap
* b
= lua_class
<lua_bitmap
>::create(L
, bitmap
.w
, bitmap
.h
);
293 lua_palette
* p
= lua_class
<lua_palette
>::create(L
);
294 for(size_t i
= 0; i
< bitmap
.w
* bitmap
.h
; i
++)
295 b
->pixels
[i
] = bitmap
.bitmap
[i
];
296 p
->colors
.resize(bitmap
.palette
.size());
297 for(size_t i
= 0; i
< bitmap
.palette
.size(); i
++)
298 p
->colors
[i
] = premultiplied_color(bitmap
.palette
[i
]);
303 function_ptr_luafun
gui_dpalette(LS
, "gui.palette_debug", [](lua_state
& L
, const std::string
& fname
) -> int {
304 lua_palette
* p
= lua_class
<lua_palette
>::get(L
, 1, fname
.c_str());
306 for(auto c
: p
->colors
)
307 messages
<< "Color #" << (i
++) << ": " << c
.orig
<< ":" << c
.origa
<< std::endl
;
312 DECLARE_LUACLASS(lua_palette
, "PALETTE");
313 DECLARE_LUACLASS(lua_bitmap
, "BITMAP");
314 DECLARE_LUACLASS(lua_dbitmap
, "DBITMAP");