Lua Bitmap WIP
This commit is contained in:
parent
0514dd989e
commit
d8319ef4a9
5 changed files with 748 additions and 7 deletions
41
include/lua/bitmap.hpp
Normal file
41
include/lua/bitmap.hpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
#ifndef _lua__bitmap__hpp__included__
|
||||
#define _lua__bitmap__hpp__included__
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
#include "core/render.hpp"
|
||||
|
||||
struct lua_bitmap
|
||||
{
|
||||
lua_bitmap(uint32_t w, uint32_t h);
|
||||
size_t width;
|
||||
size_t height;
|
||||
std::vector<uint16_t> pixels;
|
||||
};
|
||||
|
||||
struct lua_dbitmap
|
||||
{
|
||||
lua_dbitmap(uint32_t w, uint32_t h);
|
||||
size_t width;
|
||||
size_t height;
|
||||
std::vector<premultiplied_color> pixels;
|
||||
};
|
||||
|
||||
struct lua_palette
|
||||
{
|
||||
std::vector<premultiplied_color> colors;
|
||||
};
|
||||
|
||||
struct lua_loaded_bitmap
|
||||
{
|
||||
size_t w;
|
||||
size_t h;
|
||||
bool d;
|
||||
std::vector<int64_t> bitmap;
|
||||
std::vector<int64_t> palette;
|
||||
static struct lua_loaded_bitmap load(const std::string& name);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
223
manual.lyx
223
manual.lyx
|
@ -2346,6 +2346,229 @@ border: Border color (default is 0xFFFFFF (white))
|
|||
fill: Fill color (default is -1 (transparent)).
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
gui.bitmap_draw(number x, number y, bitmap bitmap, palette palette)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
Draw a bitmap on screen with specified palette.
|
||||
Parameters:
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
x: X-coordinate of left edge.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
y: Y-coordinate of top edge.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
bitmap: The bitmap to draw
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
palette: The palette to draw the bitmap using.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
gui.bitmap_draw(number x, number y, dbitmap bitmap)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
Draw a bitmap on screen.
|
||||
Parameters:
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
x: X-coordinate of left edge.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
y: Y-coordinate of top edge.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
bitmap: The bitmap to draw
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
gui.palette_new()
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
Returns a new palette (initially all transparent).
|
||||
Can be used anywhere.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
gui.bitmap_new(number w, number h, boolean direct)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
Returns a new bitmap/dbitmap.
|
||||
Can be used anywhere.
|
||||
Parameters:
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
w: The width of new bitmap
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
h: The height of new bitmap
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
direct: If true, the returned bitmap is dbitmap, otherwise bitmap.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
gui.bitmap_load(string file)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
Returns loaded bitmap/dbitmap (if bitmap, the second return value is palette
|
||||
for bitmap).
|
||||
Can be used anywhere.
|
||||
Parameters:
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
file: The name of file to load.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
gui.palette_set(palette palette, number index, number color)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
Sets color in palette.
|
||||
Can be used anywhere.
|
||||
Parameters:
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
palette: The palette to manipulate
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
index: Index of color (0-65535).
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
color: The color value.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
gui.bitmap_pset(bitmap/dbitmap bitmap, number x, number y, number color)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
Sets specified pixel in bitmap.
|
||||
Can be used anywhere.
|
||||
Parameters:
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
bitmap: The bitmap to manipulate
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
x: The x-coordinate of the pixel.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
y: The y-coordinate of the pixel.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
color: If bitmap is a bitmap, color index (0-65535).
|
||||
Otherwise color value.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
gui.bitmap_size(bitmap/dbitmap bitmap)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
Get size of bitmap.
|
||||
Can be used anywhere.
|
||||
Parameters:
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
bitmap: The bitmap to query.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
The first return is the width, the second is the height.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
gui.bitmap_blit(bitmap/dbitmap dest, number dx, number dy, bitmap/dbitmap
|
||||
src, number sx, number sy, number w, number h[, number ck])
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
Blit a part of bitmap to another.
|
||||
Can be used anywhere.
|
||||
Parameters:
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
dest: Destination to blit to.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
dx: left edge of target
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
dy: Top edge of target
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
src: The source to blit from.
|
||||
Must be of the same type as destination.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
sx: left edge of source
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
sy: Top edge of source
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
w: Width of region
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
h: Height of region.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
ck: Color key.
|
||||
Pixels of this color are not blitted.
|
||||
\end_layout
|
||||
|
||||
\begin_deeper
|
||||
\begin_layout Itemize
|
||||
If bitmaps are bitmaps, this is color index of colorkey.
|
||||
Values outside range 0-65535 cause no key to be used as colorkey.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
If bitmaps are dbitmaps, this color value of colorkey.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
May be absent or nil for no colorkey blit.
|
||||
\end_layout
|
||||
|
||||
\end_deeper
|
||||
\begin_layout Subsubsection
|
||||
gui.repaint()
|
||||
\end_layout
|
||||
|
|
128
manual.txt
128
manual.txt
|
@ -1150,29 +1150,142 @@ Draw a circle. Parameters.
|
|||
|
||||
• fill: Fill color (default is -1 (transparent)).
|
||||
|
||||
8.3.12 gui.repaint()
|
||||
8.3.12 gui.bitmap_draw(number x, number y, bitmap bitmap, palette
|
||||
palette)
|
||||
|
||||
Draw a bitmap on screen with specified palette. Parameters:
|
||||
|
||||
• x: X-coordinate of left edge.
|
||||
|
||||
• y: Y-coordinate of top edge.
|
||||
|
||||
• bitmap: The bitmap to draw
|
||||
|
||||
• palette: The palette to draw the bitmap using.
|
||||
|
||||
8.3.13 gui.bitmap_draw(number x, number y, dbitmap bitmap)
|
||||
|
||||
Draw a bitmap on screen. Parameters:
|
||||
|
||||
• x: X-coordinate of left edge.
|
||||
|
||||
• y: Y-coordinate of top edge.
|
||||
|
||||
• bitmap: The bitmap to draw
|
||||
|
||||
8.3.14 gui.palette_new()
|
||||
|
||||
Returns a new palette (initially all transparent). Can be used
|
||||
anywhere.
|
||||
|
||||
8.3.15 gui.bitmap_new(number w, number h, boolean direct)
|
||||
|
||||
Returns a new bitmap/dbitmap. Can be used anywhere. Parameters:
|
||||
|
||||
• w: The width of new bitmap
|
||||
|
||||
• h: The height of new bitmap
|
||||
|
||||
• direct: If true, the returned bitmap is dbitmap, otherwise
|
||||
bitmap.
|
||||
|
||||
8.3.16 gui.bitmap_load(string file)
|
||||
|
||||
Returns loaded bitmap/dbitmap (if bitmap, the second return value
|
||||
is palette for bitmap). Can be used anywhere. Parameters:
|
||||
|
||||
• file: The name of file to load.
|
||||
|
||||
8.3.17 gui.palette_set(palette palette, number index, number
|
||||
color)
|
||||
|
||||
Sets color in palette. Can be used anywhere. Parameters:
|
||||
|
||||
• palette: The palette to manipulate
|
||||
|
||||
• index: Index of color (0-65535).
|
||||
|
||||
• color: The color value.
|
||||
|
||||
8.3.18 gui.bitmap_pset(bitmap/dbitmap bitmap, number x, number y,
|
||||
number color)
|
||||
|
||||
Sets specified pixel in bitmap. Can be used anywhere. Parameters:
|
||||
|
||||
• bitmap: The bitmap to manipulate
|
||||
|
||||
• x: The x-coordinate of the pixel.
|
||||
|
||||
• y: The y-coordinate of the pixel.
|
||||
|
||||
• color: If bitmap is a bitmap, color index (0-65535). Otherwise
|
||||
color value.
|
||||
|
||||
8.3.19 gui.bitmap_size(bitmap/dbitmap bitmap)
|
||||
|
||||
Get size of bitmap. Can be used anywhere. Parameters:
|
||||
|
||||
• bitmap: The bitmap to query.
|
||||
|
||||
The first return is the width, the second is the height.
|
||||
|
||||
8.3.20 gui.bitmap_blit(bitmap/dbitmap dest, number dx, number dy,
|
||||
bitmap/dbitmap src, number sx, number sy, number w, number h[,
|
||||
number ck])
|
||||
|
||||
Blit a part of bitmap to another. Can be used anywhere.
|
||||
Parameters:
|
||||
|
||||
• dest: Destination to blit to.
|
||||
|
||||
• dx: left edge of target
|
||||
|
||||
• dy: Top edge of target
|
||||
|
||||
• src: The source to blit from. Must be of the same type as
|
||||
destination.
|
||||
|
||||
• sx: left edge of source
|
||||
|
||||
• sy: Top edge of source
|
||||
|
||||
• w: Width of region
|
||||
|
||||
• h: Height of region.
|
||||
|
||||
• ck: Color key. Pixels of this color are not blitted.
|
||||
|
||||
– If bitmaps are bitmaps, this is color index of colorkey.
|
||||
Values outside range 0-65535 cause no key to be used as
|
||||
colorkey.
|
||||
|
||||
– If bitmaps are dbitmaps, this color value of colorkey.
|
||||
|
||||
– May be absent or nil for no colorkey blit.
|
||||
|
||||
8.3.21 gui.repaint()
|
||||
|
||||
Request on_repaint() to happen as soon as possible. Can be used
|
||||
anywhere.
|
||||
|
||||
8.3.13 gui.subframe_update(boolean on)
|
||||
8.3.22 gui.subframe_update(boolean on)
|
||||
|
||||
Request subframe updates (calling on_paint() on subframes) to
|
||||
happen (on=true) or not happen (on=false). Can be used anywhere.
|
||||
|
||||
8.3.14 gui.screenshot(string filename)
|
||||
8.3.23 gui.screenshot(string filename)
|
||||
|
||||
Write PNG screenshot of the current frame (no drawings) to
|
||||
specified file. Can be used anywhere.
|
||||
|
||||
8.3.15 gui.color(number r, number g, number b[, number a])
|
||||
8.3.24 gui.color(number r, number g, number b[, number a])
|
||||
|
||||
Returns color (in notation Lua scripts use) corresponding to
|
||||
color (r,g,b), each component in scale 0-255. If a is specified,
|
||||
that is alpha (0 is fully transparent, 256(sic) is fully opaque).
|
||||
The default alpha is 256.
|
||||
|
||||
8.3.16 gui.status(string name, string value)
|
||||
8.3.25 gui.status(string name, string value)
|
||||
|
||||
Set status field “L[<name>]” to <value> in status area. Can be
|
||||
used anywhere.
|
||||
|
@ -2662,7 +2775,8 @@ set-axis joystick0axis19 disabled
|
|||
|
||||
• Try to autodetect if ROM is headered.
|
||||
|
||||
• Only bring up ROM patching screen if specifically requested.
|
||||
• Wxwidgets: Only bring up ROM patching screen if specifically
|
||||
requested.
|
||||
|
||||
• Allow configuring some (200+) hotkeys.
|
||||
• Allow configuring some hotkeys.
|
||||
|
||||
|
|
283
src/lua/gui-bitmap.cpp
Normal file
283
src/lua/gui-bitmap.cpp
Normal file
|
@ -0,0 +1,283 @@
|
|||
#include "core/lua-int.hpp"
|
||||
#include "core/render.hpp"
|
||||
#include "lua/bitmap.hpp"
|
||||
#include <vector>
|
||||
|
||||
lua_bitmap::lua_bitmap(uint32_t w, uint32_t h)
|
||||
{
|
||||
width = w;
|
||||
height = h;
|
||||
pixels.resize(width * height);
|
||||
memset(&pixels[0], 0, width * height);
|
||||
}
|
||||
|
||||
lua_dbitmap::lua_dbitmap(uint32_t w, uint32_t h)
|
||||
{
|
||||
width = w;
|
||||
height = h;
|
||||
pixels.resize(width * height);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
struct render_object_bitmap : public render_object
|
||||
{
|
||||
render_object_bitmap(int32_t _x, int32_t _y, lua_obj_pin<lua_bitmap>* _bitmap,
|
||||
lua_obj_pin<lua_palette>* _palette) throw()
|
||||
{
|
||||
x = _x;
|
||||
y = _y;
|
||||
b = _bitmap;
|
||||
b2 = NULL;
|
||||
p = _palette;
|
||||
}
|
||||
|
||||
render_object_bitmap(int32_t _x, int32_t _y, lua_obj_pin<lua_dbitmap>* _bitmap) throw()
|
||||
{
|
||||
x = _x;
|
||||
y = _y;
|
||||
b = NULL;
|
||||
b2 = _bitmap;
|
||||
p = NULL;
|
||||
}
|
||||
|
||||
~render_object_bitmap() throw()
|
||||
{
|
||||
delete b;
|
||||
delete b2;
|
||||
delete p;
|
||||
}
|
||||
|
||||
void operator()(struct screen& scr) throw()
|
||||
{
|
||||
size_t pallim = 0;
|
||||
size_t w, h;
|
||||
premultiplied_color* palette;
|
||||
if(b) {
|
||||
palette = &p->object()->colors[0];
|
||||
for(auto& c : p->object()->colors)
|
||||
c.set_palette(scr);
|
||||
pallim = p->object()->colors.size();
|
||||
w = b->object()->width;
|
||||
h = b->object()->height;
|
||||
} else {
|
||||
for(auto& c : b2->object()->pixels)
|
||||
c.set_palette(scr);
|
||||
w = b2->object()->width;
|
||||
h = b2->object()->height;
|
||||
}
|
||||
|
||||
int32_t xmin = 0;
|
||||
int32_t xmax = w;
|
||||
int32_t ymin = 0;
|
||||
int32_t ymax = h;
|
||||
clip_range(scr.originx, scr.width, x, xmin, xmax);
|
||||
clip_range(scr.originy, scr.height, y, ymin, ymax);
|
||||
for(int32_t r = ymin; r < ymax; r++) {
|
||||
uint32_t* rptr = scr.rowptr(y + r + scr.originy);
|
||||
size_t eptr = x + xmin + scr.originx;
|
||||
if(b)
|
||||
for(int32_t c = xmin; c < xmax; c++, eptr++) {
|
||||
uint16_t i = b->object()->pixels[r * b->object()->width + c];
|
||||
if(i < pallim)
|
||||
palette[i].apply(rptr[eptr]);
|
||||
}
|
||||
else
|
||||
for(int32_t c = xmin; c < xmax; c++, eptr++)
|
||||
b2->object()->pixels[r * b2->object()->width + c].apply(rptr[eptr]);
|
||||
}
|
||||
}
|
||||
private:
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
lua_obj_pin<lua_bitmap>* b;
|
||||
lua_obj_pin<lua_dbitmap>* b2;
|
||||
lua_obj_pin<lua_palette>* p;
|
||||
};
|
||||
|
||||
function_ptr_luafun gui_bitmap("gui.bitmap_draw", [](lua_State* LS, const std::string& fname) -> int {
|
||||
if(!lua_render_ctx)
|
||||
return 0;
|
||||
int32_t x = get_numeric_argument<int32_t>(LS, 1, fname.c_str());
|
||||
int32_t y = get_numeric_argument<int32_t>(LS, 2, fname.c_str());
|
||||
if(lua_class<lua_bitmap>::is(LS, 3)) {
|
||||
lua_class<lua_bitmap>::get(LS, 3, fname.c_str());
|
||||
lua_class<lua_palette>::get(LS, 4, fname.c_str());
|
||||
auto b = lua_class<lua_bitmap>::pin(LS, 3, fname.c_str());
|
||||
auto p = lua_class<lua_palette>::pin(LS, 4, fname.c_str());
|
||||
lua_render_ctx->queue->add(*new render_object_bitmap(x, y, b, p));
|
||||
} else if(lua_class<lua_dbitmap>::is(LS, 3)) {
|
||||
lua_class<lua_dbitmap>::get(LS, 3, fname.c_str());
|
||||
auto b = lua_class<lua_dbitmap>::pin(LS, 3, fname.c_str());
|
||||
lua_render_ctx->queue->add(*new render_object_bitmap(x, y, b));
|
||||
} else {
|
||||
lua_pushstring(LS, "Expected BITMAP or DBITMAP as argument 3 for gui.bitmap_draw.");
|
||||
lua_error(LS);
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
function_ptr_luafun gui_cpalette("gui.palette_new", [](lua_State* LS, const std::string& fname) -> int {
|
||||
lua_class<lua_palette>::create(LS);
|
||||
return 1;
|
||||
});
|
||||
|
||||
function_ptr_luafun gui_cbitmap("gui.bitmap_new", [](lua_State* LS, const std::string& fname) -> int {
|
||||
uint32_t w = get_numeric_argument<uint32_t>(LS, 1, fname.c_str());
|
||||
uint32_t h = get_numeric_argument<uint32_t>(LS, 2, fname.c_str());
|
||||
bool d = get_boolean_argument(LS, 3, fname.c_str());
|
||||
if(d)
|
||||
lua_class<lua_dbitmap>::create(LS, w, h);
|
||||
else
|
||||
lua_class<lua_bitmap>::create(LS, w, h);
|
||||
return 1;
|
||||
});
|
||||
|
||||
function_ptr_luafun gui_epalette("gui.palette_set", [](lua_State* LS, const std::string& fname) -> int {
|
||||
lua_palette* p = lua_class<lua_palette>::get(LS, 1, fname.c_str());
|
||||
uint16_t c = get_numeric_argument<uint16_t>(LS, 2, fname.c_str());
|
||||
int64_t nval = get_numeric_argument<int64_t>(LS, 3, fname.c_str());
|
||||
premultiplied_color nc(nval);
|
||||
if(p->colors.size() <= c);
|
||||
p->colors.resize(static_cast<uint32_t>(c) + 1);
|
||||
p->colors[c] = nc;
|
||||
return 0;
|
||||
});
|
||||
|
||||
function_ptr_luafun pset_bitmap("gui.bitmap_pset", [](lua_State* LS, const std::string& fname) -> int {
|
||||
uint32_t x = get_numeric_argument<uint32_t>(LS, 2, fname.c_str());
|
||||
uint32_t y = get_numeric_argument<uint32_t>(LS, 3, fname.c_str());
|
||||
if(lua_class<lua_bitmap>::is(LS, 1)) {
|
||||
lua_bitmap* b = lua_class<lua_bitmap>::get(LS, 1, fname.c_str());
|
||||
uint16_t c = get_numeric_argument<uint16_t>(LS, 4, fname.c_str());
|
||||
if(x >= b->width || y >= b->height)
|
||||
return 0;
|
||||
b->pixels[y * b->width + x] = c;
|
||||
} else if(lua_class<lua_dbitmap>::is(LS, 1)) {
|
||||
lua_dbitmap* b = lua_class<lua_dbitmap>::get(LS, 1, fname.c_str());
|
||||
int64_t c = get_numeric_argument<int64_t>(LS, 4, fname.c_str());
|
||||
if(x >= b->width || y >= b->height)
|
||||
return 0;
|
||||
b->pixels[y * b->width + x] = premultiplied_color(c);
|
||||
} else {
|
||||
lua_pushstring(LS, "Expected BITMAP or DBITMAP as argument 1 for gui.bitmap_pset.");
|
||||
lua_error(LS);
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
function_ptr_luafun size_bitmap("gui.bitmap_size", [](lua_State* LS, const std::string& fname) -> int {
|
||||
if(lua_class<lua_bitmap>::is(LS, 1)) {
|
||||
lua_bitmap* b = lua_class<lua_bitmap>::get(LS, 1, fname.c_str());
|
||||
lua_pushnumber(LS, b->width);
|
||||
lua_pushnumber(LS, b->height);
|
||||
} else if(lua_class<lua_dbitmap>::is(LS, 1)) {
|
||||
lua_dbitmap* b = lua_class<lua_dbitmap>::get(LS, 1, fname.c_str());
|
||||
lua_pushnumber(LS, b->width);
|
||||
lua_pushnumber(LS, b->height);
|
||||
} else {
|
||||
lua_pushstring(LS, "Expected BITMAP or DBITMAP as argument 1 for gui.bitmap_size.");
|
||||
lua_error(LS);
|
||||
}
|
||||
return 2;
|
||||
});
|
||||
|
||||
function_ptr_luafun blit_bitmap("gui.bitmap_blit", [](lua_State* LS, const std::string& fname) -> int {
|
||||
uint32_t dx = get_numeric_argument<uint32_t>(LS, 2, fname.c_str());
|
||||
uint32_t dy = get_numeric_argument<uint32_t>(LS, 3, fname.c_str());
|
||||
uint32_t sx = get_numeric_argument<uint32_t>(LS, 5, fname.c_str());
|
||||
uint32_t sy = get_numeric_argument<uint32_t>(LS, 6, fname.c_str());
|
||||
uint32_t w = get_numeric_argument<uint32_t>(LS, 7, fname.c_str());
|
||||
uint32_t h = get_numeric_argument<uint32_t>(LS, 8, fname.c_str());
|
||||
int64_t ck = 0x100000000ULL;
|
||||
get_numeric_argument<int64_t>(LS, 9, ck, fname.c_str());
|
||||
bool nck = false;
|
||||
premultiplied_color pck(ck);
|
||||
uint32_t ckorig = pck.orig;
|
||||
uint16_t ckoriga = pck.origa;
|
||||
if(ck == 0x100000000ULL)
|
||||
nck = true;
|
||||
if(lua_class<lua_bitmap>::is(LS, 1) && lua_class<lua_bitmap>::is(LS, 4)) {
|
||||
lua_bitmap* db = lua_class<lua_bitmap>::get(LS, 1, fname.c_str());
|
||||
lua_bitmap* sb = lua_class<lua_bitmap>::get(LS, 4, fname.c_str());
|
||||
while((dx + w > db->width || sx + w > sb->width) && w > 0)
|
||||
w--;
|
||||
while((dy + h > db->height || sy + h > sb->height) && h > 0)
|
||||
h--;
|
||||
size_t sidx = sy * sb->width + sx;
|
||||
size_t didx = dy * db->width + dx;
|
||||
size_t srskip = sb->width - w;
|
||||
size_t drskip = db->width - w;
|
||||
for(uint32_t j = 0; j < h; j++) {
|
||||
for(uint32_t i = 0; i < w; i++) {
|
||||
uint16_t pix = sb->pixels[sidx];
|
||||
if(pix != ck) //No need to check nck, as that value is out of range.
|
||||
db->pixels[didx] = pix;
|
||||
sidx++;
|
||||
didx++;
|
||||
}
|
||||
sidx += srskip;
|
||||
didx += drskip;
|
||||
}
|
||||
} else if(lua_class<lua_dbitmap>::is(LS, 1) && lua_class<lua_dbitmap>::is(LS, 1)) {
|
||||
lua_dbitmap* db = lua_class<lua_dbitmap>::get(LS, 1, fname.c_str());
|
||||
lua_dbitmap* sb = lua_class<lua_dbitmap>::get(LS, 4, fname.c_str());
|
||||
while((dx + w > db->width || sx + w > sb->width) && w > 0)
|
||||
w--;
|
||||
while((dy + h > db->height || sy + h > sb->height) && h > 0)
|
||||
h--;
|
||||
size_t sidx = sy * sb->width + sx;
|
||||
size_t didx = dy * db->width + dx;
|
||||
size_t srskip = sb->width - w;
|
||||
size_t drskip = db->width - w;
|
||||
for(uint32_t j = 0; j < h; j++) {
|
||||
for(uint32_t i = 0; i < w; i++) {
|
||||
premultiplied_color pix = sb->pixels[sidx];
|
||||
if(pix.orig != ckorig || pix.origa != ckoriga || nck)
|
||||
db->pixels[didx] = pix;
|
||||
sidx++;
|
||||
didx++;
|
||||
}
|
||||
sidx += srskip;
|
||||
didx += drskip;
|
||||
}
|
||||
} else {
|
||||
lua_pushstring(LS, "Expected BITMAP or DBITMAP as arguments 1&4 for gui.bitmap_pset.");
|
||||
lua_error(LS);
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
function_ptr_luafun gui_loadbitmap("gui.bitmap_load", [](lua_State* LS, const std::string& fname) -> int {
|
||||
std::string name = get_string_argument(LS, 1, fname.c_str());
|
||||
uint32_t w, h;
|
||||
auto bitmap = lua_loaded_bitmap::load(name);
|
||||
if(bitmap.d) {
|
||||
lua_dbitmap* b = lua_class<lua_dbitmap>::create(LS, bitmap.w, bitmap.h);
|
||||
for(size_t i = 0; i < bitmap.w * bitmap.h; i++)
|
||||
b->pixels[i] = premultiplied_color(bitmap.bitmap[i]);
|
||||
return 1;
|
||||
} else {
|
||||
lua_bitmap* b = lua_class<lua_bitmap>::create(LS, bitmap.w, bitmap.h);
|
||||
lua_palette* p = lua_class<lua_palette>::create(LS);
|
||||
for(size_t i = 0; i < bitmap.w * bitmap.h; i++)
|
||||
b->pixels[i] = bitmap.bitmap[i];
|
||||
p->colors.resize(bitmap.palette.size());
|
||||
for(size_t i = 0; i < bitmap.palette.size(); i++)
|
||||
p->colors[i] = premultiplied_color(bitmap.palette[i]);
|
||||
return 2;
|
||||
}
|
||||
});
|
||||
|
||||
function_ptr_luafun gui_dpalette("gui.palette_debug", [](lua_State* LS, const std::string& fname) -> int {
|
||||
lua_palette* p = lua_class<lua_palette>::get(LS, 1, fname.c_str());
|
||||
size_t i = 0;
|
||||
for(auto c : p->colors)
|
||||
messages << "Color #" << (i++) << ": " << c.orig << ":" << c.origa << std::endl;
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
DECLARE_LUACLASS(lua_palette, "PALETTE");
|
||||
DECLARE_LUACLASS(lua_bitmap, "BITMAP");
|
||||
DECLARE_LUACLASS(lua_dbitmap, "DBITMAP");
|
80
src/lua/loadbitmap.cpp
Normal file
80
src/lua/loadbitmap.cpp
Normal file
|
@ -0,0 +1,80 @@
|
|||
#include "lua/bitmap.hpp"
|
||||
#include "library/zip.hpp"
|
||||
#include <limits>
|
||||
|
||||
namespace
|
||||
{
|
||||
inline uint64_t tocolor(unsigned r, unsigned g, unsigned b, unsigned a)
|
||||
{
|
||||
if(!a)
|
||||
return -1;
|
||||
else
|
||||
return (static_cast<int64_t>(256 - a) << 24) | (static_cast<int64_t>(r) << 16) |
|
||||
(static_cast<int64_t>(g) << 8) | static_cast<int64_t>(b);
|
||||
}
|
||||
}
|
||||
|
||||
struct lua_loaded_bitmap lua_loaded_bitmap::load(const std::string& name)
|
||||
{
|
||||
struct lua_loaded_bitmap b;
|
||||
std::istream* file = NULL;
|
||||
try {
|
||||
std::string magic;
|
||||
unsigned pcolors;
|
||||
unsigned R;
|
||||
unsigned G;
|
||||
unsigned B;
|
||||
unsigned A;
|
||||
file = &open_file_relative(name, "");
|
||||
*file >> magic;
|
||||
if(magic != "LSNES-BITMAP")
|
||||
throw std::runtime_error("Bitmap load: Wrong magic");
|
||||
*file >> b.w;
|
||||
*file >> b.h;
|
||||
if(b.h >= std::numeric_limits<size_t>::max() / b.w)
|
||||
throw std::runtime_error("Bitmap load: Bitmap too large");
|
||||
b.bitmap.resize(b.w * b.h);
|
||||
*file >> pcolors;
|
||||
if(pcolors > 65536)
|
||||
throw std::runtime_error("Bitmap load: Palette too big");
|
||||
if(pcolors > 0) {
|
||||
//Paletted.
|
||||
b.d = false;
|
||||
b.palette.resize(pcolors);
|
||||
for(size_t i = 0; i < pcolors; i++) {
|
||||
*file >> R;
|
||||
*file >> G;
|
||||
*file >> B;
|
||||
*file >> A;
|
||||
if(R > 255 || G > 255 || B > 255 || A > 256) //Yes, a can be 256.
|
||||
throw std::runtime_error("Bitmap load: Palette entry out of range");
|
||||
b.palette[i] = tocolor(R, G, B, A);
|
||||
}
|
||||
for(size_t i = 0; i < b.w * b.h; i++) {
|
||||
*file >> R;
|
||||
if(R >= pcolors)
|
||||
throw std::runtime_error("Bitmap load: color index out of range");
|
||||
b.bitmap[i] = R;
|
||||
}
|
||||
} else {
|
||||
//Direct.
|
||||
b.d = true;
|
||||
for(size_t i = 0; i < b.w * b.h; i++) {
|
||||
*file >> R;
|
||||
*file >> G;
|
||||
*file >> B;
|
||||
*file >> A;
|
||||
if(R > 255 || G > 255 || B > 255 || A > 256) //Yes, a can be 256.
|
||||
throw std::runtime_error("Bitmap load: Color out of range");
|
||||
b.bitmap[i] = tocolor(R, G, B, A);
|
||||
}
|
||||
}
|
||||
if(!*file)
|
||||
throw std::runtime_error("Bitmap load: Error reading bitmap");
|
||||
} catch(...) {
|
||||
delete file;
|
||||
throw;
|
||||
}
|
||||
delete file;
|
||||
return b;
|
||||
}
|
Loading…
Add table
Reference in a new issue