Merge branch 'rr1-maint'
This commit is contained in:
commit
ff86d2f0c2
7 changed files with 394 additions and 217 deletions
|
@ -5,6 +5,7 @@
|
|||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
struct png_decoded_image
|
||||
{
|
||||
|
@ -15,6 +16,7 @@ struct png_decoded_image
|
|||
std::vector<uint32_t> palette;
|
||||
};
|
||||
|
||||
void decode_png(std::istream& file, png_decoded_image& out);
|
||||
void decode_png(const std::string& file, png_decoded_image& out);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -41,6 +41,7 @@ struct lua_loaded_bitmap
|
|||
bool d;
|
||||
std::vector<int64_t> bitmap;
|
||||
std::vector<int64_t> palette;
|
||||
static struct lua_loaded_bitmap load(std::istream& stream);
|
||||
static struct lua_loaded_bitmap load(const std::string& name);
|
||||
};
|
||||
|
||||
|
|
25
manual.lyx
25
manual.lyx
|
@ -1953,6 +1953,31 @@ First non-whitespace is '#': Ignored
|
|||
transparent: Fully transparent color
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
gui.bitmap_load_str(string content)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
Like gui.bitmap_load, but reads the specified string directly as content.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
gui.bitmap_load_png_str(string base64content)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
Like gui.bitmap_load_png, but reads the specified string (as base64-encoded)
|
||||
directly as content.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
gui.bitmap_load_pal_str(string content)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
Like gui.bitmap_load_pal, but reads the specified string directly as content.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
gui.repaint()
|
||||
\end_layout
|
||||
|
|
78
manual.txt
78
manual.txt
|
@ -953,34 +953,86 @@ Parameters:
|
|||
|
||||
– May be absent or nil for no colorkey blit.
|
||||
|
||||
7.3.23 gui.repaint()
|
||||
7.3.23 gui.bitmap_load_png(string filename)
|
||||
|
||||
Load a bitmap from PNG file. Parameters:
|
||||
|
||||
• filename: The name of file to load the bitmap frame.
|
||||
|
||||
Return value:
|
||||
|
||||
• If the PNG is of color type 3 (PALETTE), returns two value.
|
||||
First is BITMAP containing the image data from the PNG and
|
||||
second is PALETTE containg the palette data from the PNG.
|
||||
|
||||
• For color types 0 (GRAY), 2 (RGB), 4 (GRAY_ALPHA) and 6 (RGBA),
|
||||
returns one DBITMAP containg the image data loaded from the
|
||||
PNG.
|
||||
|
||||
7.3.24 gui.bitmap_load_pal(string filename)
|
||||
|
||||
Load a palette from file. Parameters:
|
||||
|
||||
• filename: The name of the file.
|
||||
|
||||
The kinds of lines supported
|
||||
|
||||
• Blank or just whitespace: Ignored
|
||||
|
||||
• First non-whitespace is '#': Ignored
|
||||
|
||||
• <r> <g> <b>: Fully opaque color with specified RGB values
|
||||
(0-255)
|
||||
|
||||
• <r> <g> <b> <a>: Color with specified RGB values (0-255) and
|
||||
specified alpha (0-256, 0 being fully transparent and 256 fully
|
||||
opaque).
|
||||
|
||||
• transparent: Fully transparent color
|
||||
|
||||
7.3.25 gui.bitmap_load_str(string content)
|
||||
|
||||
Like gui.bitmap_load, but reads the specified string directly as
|
||||
content.
|
||||
|
||||
7.3.26 gui.bitmap_load_png_str(string base64content)
|
||||
|
||||
Like gui.bitmap_load_png, but reads the specified string (as
|
||||
base64-encoded) directly as content.
|
||||
|
||||
7.3.27 gui.bitmap_load_pal_str(string content)
|
||||
|
||||
Like gui.bitmap_load_pal, but reads the specified string directly
|
||||
as content.
|
||||
|
||||
7.3.28 gui.repaint()
|
||||
|
||||
Request on_repaint() to happen as soon as possible. Can be used
|
||||
anywhere.
|
||||
|
||||
7.3.24 gui.subframe_update(boolean on)
|
||||
7.3.29 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.
|
||||
|
||||
7.3.25 gui.screenshot(string filename)
|
||||
7.3.30 gui.screenshot(string filename)
|
||||
|
||||
Write PNG screenshot of the current frame (no drawings) to
|
||||
specified file. Can be used anywhere.
|
||||
|
||||
7.3.26 gui.color(number r, number g, number b[, number a])
|
||||
7.3.31 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.
|
||||
|
||||
7.3.27 gui.status(string name, string value)
|
||||
7.3.32 gui.status(string name, string value)
|
||||
|
||||
Set status field “L[<name>]” to <value> in status area. Can be
|
||||
used anywhere.
|
||||
|
||||
7.3.28 gui.rainbow(number step, number steps[, number color])
|
||||
7.3.33 gui.rainbow(number step, number steps[, number color])
|
||||
|
||||
Perform hue rotation of color <color> (default bright red), by
|
||||
<step> steps. The number of steps per full rotation is given by
|
||||
|
@ -988,19 +1040,19 @@ absolute value of <steps>.
|
|||
|
||||
If <steps> is negative, the rotation will be counterclockwise.
|
||||
|
||||
7.3.29 gui.screenshot(string filename)
|
||||
7.3.34 gui.screenshot(string filename)
|
||||
|
||||
Saves a screenshot into specified file.
|
||||
|
||||
7.3.30 gui.renderq_new(number width, number height)
|
||||
7.3.35 gui.renderq_new(number width, number height)
|
||||
|
||||
Create render queue with specified reported size and return it.
|
||||
|
||||
7.3.31 gui.renderq_clear(RENDERQUEUE queue)
|
||||
7.3.36 gui.renderq_clear(RENDERQUEUE queue)
|
||||
|
||||
Clear specified render queue.
|
||||
|
||||
7.3.32 gui.renderq_set(RENDERQUEUE queue)
|
||||
7.3.37 gui.renderq_set(RENDERQUEUE queue)
|
||||
|
||||
Switch to specified render queue. Use nil as queue to switch to
|
||||
default queue.
|
||||
|
@ -1008,18 +1060,18 @@ default queue.
|
|||
• When switched to another queue, all drawing functions work and
|
||||
draw there, even outside on_video/on_paint.
|
||||
|
||||
7.3.33 gui.renderq_run(RENDERQUEUE queue)
|
||||
7.3.38 gui.renderq_run(RENDERQUEUE queue)
|
||||
|
||||
Run specified render queue, copying the objects to current render
|
||||
queue.
|
||||
|
||||
• Warning: Don't try to run the current render queue.
|
||||
|
||||
7.3.34 gui.loadfont(string filename)
|
||||
7.3.39 gui.loadfont(string filename)
|
||||
|
||||
Loads font from specified file (CUSTOMFONT object).
|
||||
|
||||
7.3.35 CUSTOMFONT(number x, number y, string text[, number fgc[,
|
||||
7.3.40 CUSTOMFONT(number x, number y, string text[, number fgc[,
|
||||
number bgc[, number hlc]]])
|
||||
|
||||
Draw string with custom font to screen. The parameters are the
|
||||
|
|
|
@ -690,9 +690,10 @@ badtype:
|
|||
if(interlace == 1) return *new png_interlacing_adam(3);
|
||||
throw std::runtime_error("Unknown interlace type");
|
||||
}
|
||||
}
|
||||
|
||||
void decode_png(std::istream& stream, png_decoded_image& out)
|
||||
{
|
||||
void decode_png(std::istream& stream, png_decoded_image& out)
|
||||
{
|
||||
png_dechunker dechunk(stream);
|
||||
if(!dechunk.next_chunk())
|
||||
throw std::runtime_error("PNG file has no chunks");
|
||||
|
@ -810,7 +811,6 @@ out:
|
|||
out.has_palette = (hdr.type == 3);
|
||||
out.width = hdr.width;
|
||||
out.height = hdr.height;
|
||||
}
|
||||
}
|
||||
|
||||
void decode_png(const std::string& file, png_decoded_image& out)
|
||||
|
@ -850,5 +850,4 @@ int main(int argc, char** argv)
|
|||
}
|
||||
//evaluate-lua b,p=gui.bitmap_load_png("/tmp/tbgn2c16.png"); on_paint = function() gui.bitmap_draw(0,0,b,p); end
|
||||
|
||||
|
||||
*/
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "lua/bitmap.hpp"
|
||||
#include "library/threadtypes.hpp"
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
|
||||
lua_bitmap::lua_bitmap(uint32_t w, uint32_t h)
|
||||
{
|
||||
|
@ -300,9 +301,10 @@ namespace
|
|||
return 0;
|
||||
});
|
||||
|
||||
function_ptr_luafun gui_loadbitmap(LS, "gui.bitmap_load", [](lua_state& L, const std::string& fname) -> int {
|
||||
std::string name = L.get_string(1, fname.c_str());
|
||||
auto bitmap = lua_loaded_bitmap::load(name);
|
||||
int bitmap_load_fn(lua_state& L, std::function<lua_loaded_bitmap()> src)
|
||||
{
|
||||
uint32_t w, h;
|
||||
auto bitmap = src();
|
||||
if(bitmap.d) {
|
||||
lua_dbitmap* b = lua_class<lua_dbitmap>::create(L, bitmap.w, bitmap.h);
|
||||
for(size_t i = 0; i < bitmap.w * bitmap.h; i++)
|
||||
|
@ -318,6 +320,20 @@ namespace
|
|||
p->colors[i] = premultiplied_color(bitmap.palette[i]);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
function_ptr_luafun gui_loadbitmap(LS, "gui.bitmap_load", [](lua_state& L, const std::string& fname) -> int {
|
||||
std::string name = L.get_string(1, fname.c_str());
|
||||
return bitmap_load_fn(L, [&name]() -> lua_loaded_bitmap { return lua_loaded_bitmap::load(name); });
|
||||
});
|
||||
|
||||
function_ptr_luafun gui_loadbitmap2(LS, "gui.bitmap_load_str", [](lua_state& L, const std::string& fname)
|
||||
-> int {
|
||||
std::string contents = L.get_string(1, fname.c_str());
|
||||
return bitmap_load_fn(L, [&contents]() -> lua_loaded_bitmap {
|
||||
std::istringstream strm(contents);
|
||||
return lua_loaded_bitmap::load(strm);
|
||||
});
|
||||
});
|
||||
|
||||
inline int64_t mangle_color(uint32_t c)
|
||||
|
@ -328,11 +344,60 @@ namespace
|
|||
return ((256 - (c >> 24) - (c >> 31)) << 24) | (c & 0xFFFFFF);
|
||||
}
|
||||
|
||||
function_ptr_luafun gui_loadbitmappng(LS, "gui.bitmap_load_png", [](lua_state& L, const std::string& fname)
|
||||
-> int {
|
||||
std::string name = L.get_string(1, fname.c_str());
|
||||
int base64val(char ch)
|
||||
{
|
||||
if(ch >= 'A' && ch <= 'Z')
|
||||
return ch - 65;
|
||||
if(ch >= 'a' && ch <= 'z')
|
||||
return ch - 97 + 26;
|
||||
if(ch >= '0' && ch <= '9')
|
||||
return ch - 48 + 52;
|
||||
if(ch == '+')
|
||||
return 62;
|
||||
if(ch == '/')
|
||||
return 63;
|
||||
if(ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n')
|
||||
return -1;
|
||||
if(ch == '=')
|
||||
return -2;
|
||||
return -3;
|
||||
}
|
||||
|
||||
std::string base64_decode(const std::string& str)
|
||||
{
|
||||
bool end = 0;
|
||||
uint32_t memory = 0;
|
||||
uint32_t memsize = 1;
|
||||
int posmod = 0;
|
||||
std::ostringstream x;
|
||||
for(auto i : str) {
|
||||
int v = base64val(i);
|
||||
if(v == -1)
|
||||
continue;
|
||||
posmod = (posmod + 1) & 3;
|
||||
if(v == -2 && (posmod == 1 || posmod == 2))
|
||||
throw std::runtime_error("Invalid Base64");
|
||||
if(v == -2) {
|
||||
end = true;
|
||||
continue;
|
||||
}
|
||||
if(v == -3 || end)
|
||||
throw std::runtime_error("Invalid Base64");
|
||||
memory = memory * 64 + v;
|
||||
memsize = memsize * 64;
|
||||
if(memsize >= 256) {
|
||||
memsize >>= 8;
|
||||
x << static_cast<uint8_t>(memory / memsize);
|
||||
memory %= memsize;
|
||||
}
|
||||
}
|
||||
return x.str();
|
||||
}
|
||||
|
||||
int bitmap_load_png_fn(lua_state& L, std::function<void(png_decoded_image&)> src)
|
||||
{
|
||||
png_decoded_image img;
|
||||
decode_png(name, img);
|
||||
src(img);
|
||||
if(img.has_palette) {
|
||||
lua_bitmap* b = lua_class<lua_bitmap>::create(L, img.width, img.height);
|
||||
lua_palette* p = lua_class<lua_palette>::create(L);
|
||||
|
@ -348,13 +413,25 @@ namespace
|
|||
b->pixels[i] = premultiplied_color(mangle_color(img.data[i]));
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function_ptr_luafun gui_loadpalette(LS, "gui.bitmap_load_pal", [](lua_state& L, const std::string& fname)
|
||||
function_ptr_luafun gui_loadbitmappng(LS, "gui.bitmap_load_png", [](lua_state& L, const std::string& fname)
|
||||
-> int {
|
||||
std::string name = L.get_string(1, fname.c_str());
|
||||
std::istream& s = open_file_relative(name, "");
|
||||
try {
|
||||
return bitmap_load_png_fn(L, [&name](png_decoded_image& img) { decode_png(name, img); });
|
||||
});
|
||||
|
||||
function_ptr_luafun gui_loadbitmappng2(LS, "gui.bitmap_load_png_str", [](lua_state& L,
|
||||
const std::string& fname) -> int {
|
||||
std::string contents = base64_decode(L.get_string(1, fname.c_str()));
|
||||
return bitmap_load_png_fn(L, [&contents](png_decoded_image& img) {
|
||||
std::istringstream strm(contents);
|
||||
decode_png(strm, img);
|
||||
});
|
||||
});
|
||||
|
||||
int bitmap_palette_fn(lua_state& L, std::istream& s)
|
||||
{
|
||||
lua_palette* p = lua_class<lua_palette>::create(L);
|
||||
while(s) {
|
||||
std::string line;
|
||||
|
@ -384,14 +461,30 @@ namespace
|
|||
} else if(!regex_match("[ \t]*(#.*)?", line))
|
||||
throw std::runtime_error("Invalid line format (" + line + ")");
|
||||
}
|
||||
delete &s;
|
||||
return 1;
|
||||
}
|
||||
|
||||
function_ptr_luafun gui_loadpalette(LS, "gui.bitmap_load_pal", [](lua_state& L, const std::string& fname)
|
||||
-> int {
|
||||
std::string name = L.get_string(1, fname.c_str());
|
||||
std::istream& s = open_file_relative(name, "");
|
||||
try {
|
||||
int r = bitmap_palette_fn(L, s);
|
||||
delete &s;
|
||||
return r;
|
||||
} catch(...) {
|
||||
delete &s;
|
||||
throw;
|
||||
}
|
||||
});
|
||||
|
||||
function_ptr_luafun gui_loadpalette2(LS, "gui.bitmap_load_pal_str", [](lua_state& L, const std::string& fname)
|
||||
-> int {
|
||||
std::string content = L.get_string(1, fname.c_str());
|
||||
std::istringstream s(content);
|
||||
return bitmap_palette_fn(L, s);
|
||||
});
|
||||
|
||||
function_ptr_luafun gui_dpalette(LS, "gui.palette_debug", [](lua_state& L, const std::string& fname) -> int {
|
||||
lua_palette* p = lua_class<lua_palette>::get(L, 1, fname.c_str());
|
||||
size_t i = 0;
|
||||
|
|
|
@ -14,27 +14,24 @@ namespace
|
|||
}
|
||||
}
|
||||
|
||||
struct lua_loaded_bitmap lua_loaded_bitmap::load(const std::string& name)
|
||||
struct lua_loaded_bitmap lua_loaded_bitmap::load(std::istream& file)
|
||||
{
|
||||
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;
|
||||
file >> magic;
|
||||
if(magic != "LSNES-BITMAP")
|
||||
throw std::runtime_error("Bitmap load: Wrong magic");
|
||||
*file >> b.w;
|
||||
*file >> b.h;
|
||||
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;
|
||||
file >> pcolors;
|
||||
if(pcolors > 65536)
|
||||
throw std::runtime_error("Bitmap load: Palette too big");
|
||||
if(pcolors > 0) {
|
||||
|
@ -42,16 +39,16 @@ struct lua_loaded_bitmap lua_loaded_bitmap::load(const std::string& name)
|
|||
b.d = false;
|
||||
b.palette.resize(pcolors);
|
||||
for(size_t i = 0; i < pcolors; i++) {
|
||||
*file >> R;
|
||||
*file >> G;
|
||||
*file >> B;
|
||||
*file >> A;
|
||||
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;
|
||||
file >> R;
|
||||
if(R >= pcolors)
|
||||
throw std::runtime_error("Bitmap load: color index out of range");
|
||||
b.bitmap[i] = R;
|
||||
|
@ -60,21 +57,29 @@ struct lua_loaded_bitmap lua_loaded_bitmap::load(const std::string& name)
|
|||
//Direct.
|
||||
b.d = true;
|
||||
for(size_t i = 0; i < b.w * b.h; i++) {
|
||||
*file >> R;
|
||||
*file >> G;
|
||||
*file >> B;
|
||||
*file >> A;
|
||||
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)
|
||||
if(!file)
|
||||
throw std::runtime_error("Bitmap load: Error reading bitmap");
|
||||
}
|
||||
|
||||
struct lua_loaded_bitmap lua_loaded_bitmap::load(const std::string& name)
|
||||
{
|
||||
struct lua_loaded_bitmap b;
|
||||
std::istream& file = open_file_relative(name, "");
|
||||
try {
|
||||
b = lua_loaded_bitmap::load(file);
|
||||
delete &file;
|
||||
return b;
|
||||
} catch(...) {
|
||||
delete file;
|
||||
delete &file;
|
||||
throw;
|
||||
}
|
||||
delete file;
|
||||
return b;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue