Lua: gui.rainbow

This is the rainbow hue shift function.
This commit is contained in:
Ilari Liusvaara 2012-04-02 18:05:46 +03:00
parent 236da32c49
commit 6ad1dd7a0d
3 changed files with 82 additions and 3 deletions

View file

@ -2727,6 +2727,19 @@ L[<name>]
Can be used anywhere.
\end_layout
\begin_layout Subsubsection
gui.rainbow(number step, number steps[, number color])
\end_layout
\begin_layout Standard
Perform hue rotation of color <color> (default bright red), by <step> steps.
The number of steps per full rotation is given by absolute value of <steps>.
\end_layout
\begin_layout Standard
If <steps> is negative, the rotation will be counterclockwise.
\end_layout
\begin_layout Subsection
table input
\end_layout

View file

@ -1348,6 +1348,14 @@ The default alpha is 256.
Set status field “L[<name>]” to <value> in status area. Can be
used anywhere.
8.3.26 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
absolute value of <steps>.
If <steps> is negative, the rotation will be counterclockwise.
8.4 table input
Input handling. Only available in on_input callback.
@ -1740,7 +1748,7 @@ Called if savestate goes wrong.
8.10.12 Callback: on_post_save(string name, boolean is_savestate)
Called on successful savaestate. is_savestate gives if this was a
savestate or a movie.
savestate or a
8.10.13 Callback: on_quit()
@ -2623,7 +2631,7 @@ set-axis joystick0axis19 disabled
• Remove calls to runtosave() that aren't supposed to be there
• Lua function: movie.read_rtc()
• Lua function: read_rtc()
• Ignore src/fonts/font.cpp
@ -2844,7 +2852,7 @@ set-axis joystick0axis19 disabled
• Wxwidgets: 128 -> 1024 Autohold slots (in case more are
needed).
• Don't append trailing '-' to prefix when saving movie.
• Don't append trailing '-' to prefix when saving
• Fix ROM/savestate handling (don't let user mismatch ROM and
savestates).

View file

@ -1,5 +1,6 @@
#include "core/lua-int.hpp"
#include "core/window.hpp"
#include "library/minmax.hpp"
namespace
{
@ -73,4 +74,61 @@ namespace
return 1;
});
//0: m
//1: M
//2: m + phue
//3: M - phue
uint8_t hsl2rgb_flags[] = {24, 52, 6, 13, 33, 19};
uint32_t shifthue(uint32_t color, double shift)
{
int16_t R = (color >> 16) & 0xFF;
int16_t G = (color >> 8) & 0xFF;
int16_t B = color & 0xFF;
int16_t m = min(R, min(G, B));
int16_t M = max(R, max(G, B));
int16_t S = M - m;
if(!S)
return color; //Grey.
int16_t hue;
if(R == M)
hue = G - B + 6 * S;
else if(G == M)
hue = B - R + 2 * S;
else
hue = R - G + 4 * S;
int16_t ohue = hue % (6 * S);
hue = (hue + static_cast<uint32_t>(shift * S)) % (6 * S);
uint32_t V[4];
V[0] = m;
V[1] = M;
V[2] = m + hue % S;
V[3] = M - hue % S;
uint8_t flag = hsl2rgb_flags[hue / S];
return (V[(flag >> 4) & 3] << 16) | (V[(flag >> 2) & 3] << 8) | (V[flag & 3]);
}
function_ptr_luafun gui_rainbow("gui.rainbow", [](lua_State* LS, const std::string& fname) -> int {
int64_t basecolor = 0x00FF0000;
uint64_t step = get_numeric_argument<uint64_t>(LS, 1, fname.c_str());
int32_t steps = get_numeric_argument<int32_t>(LS, 2, fname.c_str());
get_numeric_argument<int64_t>(LS, 3, basecolor, fname.c_str());
if(!steps) {
lua_pushstring(LS, "Expected nonzero steps for gui.rainbow");
lua_error(LS);
}
if(basecolor < 0) {
//Special: Any rotation of transparent is transparent.
lua_pushnumber(LS, -1);
return 1;
}
uint32_t asteps = std::abs(steps);
if(steps < 0)
step = asteps - step % asteps; //Reverse order.
double hueshift = 6.0 * (step % asteps) / asteps;
basecolor = shifthue(basecolor & 0xFFFFFF, hueshift) | (basecolor & 0xFF000000);
lua_pushnumber(LS, basecolor);
return 1;
});
}