LiteRGSS 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/ext/LiteRGSS/Bitmap.cpp +316 -0
- data/ext/LiteRGSS/Bitmap.h +24 -0
- data/ext/LiteRGSS/BlendMode.cpp +202 -0
- data/ext/LiteRGSS/BlendMode.h +20 -0
- data/ext/LiteRGSS/CBitmap_Element.cpp +50 -0
- data/ext/LiteRGSS/CBitmap_Element.h +17 -0
- data/ext/LiteRGSS/CDrawable_Element.cpp +38 -0
- data/ext/LiteRGSS/CDrawable_Element.h +30 -0
- data/ext/LiteRGSS/CRect_Element.h +15 -0
- data/ext/LiteRGSS/CShaderSprite_Element.cpp +17 -0
- data/ext/LiteRGSS/CShaderSprite_Element.h +17 -0
- data/ext/LiteRGSS/CSprite_Element.cpp +15 -0
- data/ext/LiteRGSS/CSprite_Element.h +36 -0
- data/ext/LiteRGSS/CText_Element.cpp +12 -0
- data/ext/LiteRGSS/CText_Element.h +29 -0
- data/ext/LiteRGSS/CTone_Element.h +17 -0
- data/ext/LiteRGSS/CViewport_Element.cpp +224 -0
- data/ext/LiteRGSS/CViewport_Element.h +57 -0
- data/ext/LiteRGSS/Color.cpp +200 -0
- data/ext/LiteRGSS/Color.h +22 -0
- data/ext/LiteRGSS/Fonts.cpp +126 -0
- data/ext/LiteRGSS/Fonts.h +20 -0
- data/ext/LiteRGSS/Graphics.cpp +314 -0
- data/ext/LiteRGSS/Graphics.h +31 -0
- data/ext/LiteRGSS/Graphics.local.cpp +365 -0
- data/ext/LiteRGSS/Graphics.local.h +37 -0
- data/ext/LiteRGSS/Image.cpp +460 -0
- data/ext/LiteRGSS/Image.h +32 -0
- data/ext/LiteRGSS/Input.cpp +664 -0
- data/ext/LiteRGSS/Input.h +38 -0
- data/ext/LiteRGSS/LiteRGSS.cpp +34 -0
- data/ext/LiteRGSS/LiteRGSS.h +113 -0
- data/ext/LiteRGSS/Rect.cpp +324 -0
- data/ext/LiteRGSS/Rect.h +24 -0
- data/ext/LiteRGSS/Shader.cpp +279 -0
- data/ext/LiteRGSS/Shader.h +13 -0
- data/ext/LiteRGSS/ShaderSprite.cpp +78 -0
- data/ext/LiteRGSS/ShaderSprite.h +8 -0
- data/ext/LiteRGSS/Sprite.cpp +495 -0
- data/ext/LiteRGSS/Sprite.h +43 -0
- data/ext/LiteRGSS/Table.cpp +228 -0
- data/ext/LiteRGSS/Table.h +29 -0
- data/ext/LiteRGSS/Table32.cpp +228 -0
- data/ext/LiteRGSS/Table32.h +29 -0
- data/ext/LiteRGSS/Text.cpp +574 -0
- data/ext/LiteRGSS/Text.h +52 -0
- data/ext/LiteRGSS/Texture.hpp +735 -0
- data/ext/LiteRGSS/Tone.cpp +228 -0
- data/ext/LiteRGSS/Tone.h +22 -0
- data/ext/LiteRGSS/Viewport.cpp +491 -0
- data/ext/LiteRGSS/Viewport.h +33 -0
- data/ext/LiteRGSS/Yuki.cpp +29 -0
- data/ext/LiteRGSS/Yuki.h +8 -0
- data/ext/LiteRGSS/Yuki_Gif.cpp +218 -0
- data/ext/LiteRGSS/Yuki_Gif.h +25 -0
- data/ext/LiteRGSS/extconf.rb +8 -0
- data/ext/LiteRGSS/libnsgif.c +1169 -0
- data/ext/LiteRGSS/libnsgif.h +183 -0
- data/ext/LiteRGSS/libnsgif.hpp +184 -0
- data/ext/LiteRGSS/lodepng.cpp +6245 -0
- data/ext/LiteRGSS/lodepng.h +1769 -0
- data/ext/LiteRGSS/lzw.c +377 -0
- data/ext/LiteRGSS/lzw.h +105 -0
- data/ext/LiteRGSS/sf_Text2.cpp +690 -0
- data/ext/LiteRGSS/sf_Text2.hpp +549 -0
- data/ext/LiteRGSS/utils/log.h +21 -0
- metadata +112 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
#ifndef GR_HEADER
|
2
|
+
#define GR_HEADER
|
3
|
+
#include "CViewport_Element.h"
|
4
|
+
#include "CSprite_Element.h"
|
5
|
+
#include "CShaderSprite_Element.h"
|
6
|
+
#include <SFML/Graphics.hpp>
|
7
|
+
|
8
|
+
VALUE rb_Graphics_start(VALUE self);
|
9
|
+
VALUE rb_Graphics_stop(VALUE self);
|
10
|
+
VALUE rb_Graphics_update(VALUE self);
|
11
|
+
VALUE rb_Graphics_snap_to_bitmap(VALUE self);
|
12
|
+
VALUE rb_Graphics_freeze(VALUE self);
|
13
|
+
VALUE rb_Graphics_transition(int argc, VALUE* argv, VALUE self);
|
14
|
+
VALUE rb_Graphics_list_res(VALUE self);
|
15
|
+
VALUE rb_Graphics_get_frame_count(VALUE self);
|
16
|
+
VALUE rb_Graphics_set_frame_count(VALUE self, VALUE val);
|
17
|
+
VALUE rb_Graphics_width(VALUE self);
|
18
|
+
VALUE rb_Graphics_height(VALUE self);
|
19
|
+
VALUE rb_Graphics_ReloadStack(VALUE self);
|
20
|
+
VALUE rb_Graphics_update_no_input_count(VALUE self);
|
21
|
+
VALUE rb_Graphics_update_only_input(VALUE self);
|
22
|
+
VALUE rb_Graphics_getBrightness(VALUE self);
|
23
|
+
VALUE rb_Graphics_setBrightness(VALUE self, VALUE brightness);
|
24
|
+
VALUE rb_Graphics_getShader(VALUE self);
|
25
|
+
VALUE rb_Graphics_setShader(VALUE self, VALUE shader);
|
26
|
+
|
27
|
+
void global_Graphics_Bind(CDrawable_Element* element);
|
28
|
+
void rb_Sprite_Free(void* data);
|
29
|
+
|
30
|
+
extern double Graphics_Scale;
|
31
|
+
#endif
|
@@ -0,0 +1,365 @@
|
|
1
|
+
#include "LiteRGSS.h"
|
2
|
+
#include "CViewport_Element.h"
|
3
|
+
#include "Graphics.local.h"
|
4
|
+
|
5
|
+
double Graphics_Scale = 1;
|
6
|
+
bool SmoothScreen = false;
|
7
|
+
bool RGSSTransition = false;
|
8
|
+
unsigned char Graphics_Brightness = 255;
|
9
|
+
sf::RenderTexture* Graphics_Render = nullptr;
|
10
|
+
sf::RenderStates* Graphics_States = nullptr;
|
11
|
+
|
12
|
+
void* local_Graphics_Update_Internal(void* data)
|
13
|
+
{
|
14
|
+
GraphicUpdateMessage* message = nullptr;
|
15
|
+
if(game_window->isOpen())
|
16
|
+
{
|
17
|
+
/* Draw Processing */
|
18
|
+
game_window->clear();
|
19
|
+
local_Graphics_Update_Draw((std::vector<CDrawable_Element*>*)data);
|
20
|
+
game_window->display();
|
21
|
+
}
|
22
|
+
else
|
23
|
+
{
|
24
|
+
message = new GraphicUpdateMessage();
|
25
|
+
message->errorObject = rb_eStoppedGraphics;
|
26
|
+
message->message = "Game Window was closed during Graphics.update by a unknow cause...";
|
27
|
+
}
|
28
|
+
return message;
|
29
|
+
}
|
30
|
+
|
31
|
+
void local_Graphics_Update_Process_Event(GraphicUpdateMessage*& message)
|
32
|
+
{
|
33
|
+
if(message != nullptr) // We'll try not to cause other error during this
|
34
|
+
return;
|
35
|
+
sf::Event event;
|
36
|
+
L_EnteredText.clear();
|
37
|
+
while(game_window->pollEvent(event))
|
38
|
+
{
|
39
|
+
switch(event.type)
|
40
|
+
{
|
41
|
+
case sf::Event::EventType::Closed:
|
42
|
+
message = new GraphicUpdateMessage();
|
43
|
+
message->errorObject = rb_eClosedWindow;
|
44
|
+
message->message = "Game Window has been closed by user.";
|
45
|
+
return;
|
46
|
+
case sf::Event::EventType::KeyPressed:
|
47
|
+
L_Input_Update_Key(event.key.code, true);
|
48
|
+
break;
|
49
|
+
case sf::Event::EventType::KeyReleased:
|
50
|
+
L_Input_Update_Key(event.key.code, false);
|
51
|
+
break;
|
52
|
+
case sf::Event::EventType::JoystickButtonPressed:
|
53
|
+
L_Input_Update_Joy(event.joystickButton.joystickId, event.joystickButton.button, true);
|
54
|
+
break;
|
55
|
+
case sf::Event::EventType::JoystickButtonReleased:
|
56
|
+
L_Input_Update_Joy(event.joystickButton.joystickId, event.joystickButton.button, false);
|
57
|
+
break;
|
58
|
+
case sf::Event::EventType::JoystickMoved:
|
59
|
+
L_Input_Update_JoyPos(event.joystickMove.joystickId,
|
60
|
+
event.joystickMove.axis,
|
61
|
+
event.joystickMove.position);
|
62
|
+
break;
|
63
|
+
case sf::Event::EventType::MouseMoved:
|
64
|
+
L_Input_Mouse_Pos_Update(event.mouseMove.x, event.mouseMove.y);
|
65
|
+
break;
|
66
|
+
case sf::Event::EventType::MouseButtonPressed:
|
67
|
+
L_Input_Mouse_Button_Update(event.mouseButton.button, true);
|
68
|
+
L_Input_Mouse_Pos_Update(event.mouseButton.x, event.mouseButton.y);
|
69
|
+
break;
|
70
|
+
case sf::Event::EventType::MouseButtonReleased:
|
71
|
+
L_Input_Mouse_Button_Update(event.mouseButton.button, false);
|
72
|
+
L_Input_Mouse_Pos_Update(event.mouseButton.x, event.mouseButton.y);
|
73
|
+
break;
|
74
|
+
case sf::Event::EventType::MouseWheelScrolled:
|
75
|
+
if(event.mouseWheelScroll.wheel == sf::Mouse::Wheel::VerticalWheel)
|
76
|
+
L_Input_Mouse_Wheel_Update(static_cast<long>(event.mouseWheelScroll.delta));
|
77
|
+
L_Input_Mouse_Pos_Update(event.mouseWheelScroll.x, event.mouseWheelScroll.y);
|
78
|
+
break;
|
79
|
+
case sf::Event::EventType::MouseLeft:
|
80
|
+
L_Input_Mouse_Pos_Update(-256, -256);
|
81
|
+
break;
|
82
|
+
case sf::Event::EventType::TextEntered:
|
83
|
+
L_EnteredText.append((char*)sf::String(event.text.unicode).toUtf8().c_str());
|
84
|
+
break;
|
85
|
+
}
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
VALUE local_Graphics_Update_RaiseError(VALUE self, GraphicUpdateMessage* message)
|
90
|
+
{
|
91
|
+
/* If the error is ClosedWindowError, we manage the window closing
|
92
|
+
* When @on_close is defined to a proc, @on_close can decide if the window closing is allowed or not
|
93
|
+
* or do things before closing the window
|
94
|
+
* That's a kind of rescue process
|
95
|
+
*/
|
96
|
+
if(message->errorObject == rb_eClosedWindow)
|
97
|
+
{
|
98
|
+
VALUE closeHandle = rb_iv_get(self, "@on_close");
|
99
|
+
if(closeHandle != Qnil)
|
100
|
+
{
|
101
|
+
VALUE handleClass = rb_class_of(closeHandle);
|
102
|
+
if(handleClass == rb_cProc)
|
103
|
+
if(rb_proc_call(closeHandle, rb_ary_new()) == Qfalse)
|
104
|
+
{
|
105
|
+
InsideGraphicsUpdate = false;
|
106
|
+
return self; /* If the proc returns false we doesn't show the exception */
|
107
|
+
}
|
108
|
+
}
|
109
|
+
local_Graphics_Clear_Stack();
|
110
|
+
game_window->close();
|
111
|
+
delete game_window;
|
112
|
+
game_window = nullptr;
|
113
|
+
}
|
114
|
+
/* We raise the message */
|
115
|
+
InsideGraphicsUpdate = false;
|
116
|
+
rb_raise(message->errorObject, "%s", message->message);
|
117
|
+
return self;
|
118
|
+
}
|
119
|
+
|
120
|
+
void local_Graphics_Update_Draw(std::vector<CDrawable_Element*>* stack)
|
121
|
+
{
|
122
|
+
bool was_viewport = false;
|
123
|
+
sf::View defview = game_window->getDefaultView();
|
124
|
+
sf::RenderTarget* render_target = game_window;
|
125
|
+
// Setting the default view parameters
|
126
|
+
defview.setSize(ScreenWidth, ScreenHeight);
|
127
|
+
defview.setCenter(round(ScreenWidth / 2.0f), round(ScreenHeight / 2.0f));
|
128
|
+
// Appying the default view to final renders
|
129
|
+
game_window->setView(defview);
|
130
|
+
if (Graphics_Render)
|
131
|
+
{
|
132
|
+
Graphics_Render->setView(defview);
|
133
|
+
Graphics_Render->clear();
|
134
|
+
render_target = Graphics_Render;
|
135
|
+
}
|
136
|
+
// Rendering stuff
|
137
|
+
for(auto element = stack->begin();element != stack->end(); element++)
|
138
|
+
{
|
139
|
+
if(was_viewport && !(*element)->isViewport())
|
140
|
+
render_target->setView(defview);
|
141
|
+
was_viewport = (*element)->isViewport();
|
142
|
+
(*element)->draw(*render_target);
|
143
|
+
}
|
144
|
+
// Drawing render to window if finished
|
145
|
+
if (Graphics_Render)
|
146
|
+
{
|
147
|
+
Graphics_Render->display();
|
148
|
+
sf::Sprite sp(Graphics_Render->getTexture());
|
149
|
+
game_window->draw(sp, *Graphics_States);
|
150
|
+
}
|
151
|
+
// Display transition sprite
|
152
|
+
if (Graphics_freeze_sprite != nullptr)
|
153
|
+
{
|
154
|
+
if (RGSSTransition)
|
155
|
+
game_window->draw(*Graphics_freeze_sprite, Graphics_freeze_shader);
|
156
|
+
else
|
157
|
+
game_window->draw(*Graphics_freeze_sprite);
|
158
|
+
}
|
159
|
+
// Update the brightness (applied to game_window)
|
160
|
+
if (Graphics_Brightness != 255)
|
161
|
+
local_Graphics_DrawBrightness();
|
162
|
+
}
|
163
|
+
|
164
|
+
void local_Graphics_DrawBrightness()
|
165
|
+
{
|
166
|
+
sf::Vertex vertices[4];
|
167
|
+
sf::Vector2u size = game_window->getSize();
|
168
|
+
vertices[0].position = sf::Vector2f(0, 0);
|
169
|
+
vertices[1].position = sf::Vector2f(0, size.y);
|
170
|
+
vertices[2].position = sf::Vector2f(size.x, 0);
|
171
|
+
vertices[3].position = sf::Vector2f(size.x, size.y);
|
172
|
+
vertices[0].color = vertices[1].color = vertices[2].color = vertices[3].color = sf::Color(0, 0, 0, 255 - Graphics_Brightness);
|
173
|
+
game_window->draw(vertices, 4, sf::PrimitiveType::TriangleStrip);
|
174
|
+
}
|
175
|
+
|
176
|
+
void local_LoadVideoModeFromConfigs(sf::VideoMode& vmode)
|
177
|
+
{
|
178
|
+
ID swidth = rb_intern("ScreenWidth");
|
179
|
+
ID sheight = rb_intern("ScreenHeight");
|
180
|
+
ID sscale = rb_intern("ScreenScale");
|
181
|
+
long max_width, max_height = 0xFFFFFF;
|
182
|
+
long pixdepth = 32;
|
183
|
+
double scale = 1;
|
184
|
+
std::vector<sf::VideoMode> modes = sf::VideoMode::getFullscreenModes();
|
185
|
+
/* If there's a fullscreen mode */
|
186
|
+
if(modes.size() > 0)
|
187
|
+
{
|
188
|
+
max_width = modes[0].width;
|
189
|
+
max_height = modes[0].height;
|
190
|
+
vmode.bitsPerPixel = modes[0].bitsPerPixel;
|
191
|
+
}
|
192
|
+
/* Adjust Width */
|
193
|
+
if(rb_const_defined(rb_mConfig, swidth))
|
194
|
+
vmode.width = normalize_long(rb_num2long(rb_const_get(rb_mConfig, swidth)), 160, max_width);
|
195
|
+
/* Adjust Height */
|
196
|
+
if(rb_const_defined(rb_mConfig, sheight))
|
197
|
+
vmode.height = normalize_long(rb_num2long(rb_const_get(rb_mConfig, sheight)), 144, max_height);
|
198
|
+
/* Adjust Scale */
|
199
|
+
if(rb_const_defined(rb_mConfig, sscale))
|
200
|
+
scale = normalize_double(NUM2DBL(rb_const_get(rb_mConfig, sscale)), 0.1, 10);
|
201
|
+
ScreenWidth = vmode.width;
|
202
|
+
ScreenHeight = vmode.height;
|
203
|
+
vmode.width *= scale;
|
204
|
+
vmode.height *= scale;
|
205
|
+
Graphics_Scale = scale;
|
206
|
+
}
|
207
|
+
|
208
|
+
const sf::String local_LoadTitleFromConfigs()
|
209
|
+
{
|
210
|
+
ID title = rb_intern("Title");
|
211
|
+
if(rb_const_defined(rb_mConfig, title))
|
212
|
+
{
|
213
|
+
VALUE str_title = rb_const_get(rb_mConfig, title);
|
214
|
+
rb_check_type(str_title, T_STRING);
|
215
|
+
std::string str(RSTRING_PTR(str_title));
|
216
|
+
return sf::String::fromUtf8(str.begin(), str.end());
|
217
|
+
}
|
218
|
+
return sf::String("LiteRGSS");
|
219
|
+
}
|
220
|
+
|
221
|
+
unsigned int local_LoadFrameRateFromConfigs()
|
222
|
+
{
|
223
|
+
ID framerate = rb_intern("FrameRate");
|
224
|
+
if(rb_const_defined(rb_mConfig, framerate))
|
225
|
+
return normalize_long(rb_num2long(rb_const_get(rb_mConfig, framerate)), 1, 120);
|
226
|
+
return 60;
|
227
|
+
}
|
228
|
+
|
229
|
+
bool local_LoadVSYNCFromConfigs()
|
230
|
+
{
|
231
|
+
ID vsync = rb_intern("Vsync");
|
232
|
+
if(rb_const_defined(rb_mConfig, vsync))
|
233
|
+
return RTEST(rb_const_get(rb_mConfig, vsync));
|
234
|
+
return true;
|
235
|
+
}
|
236
|
+
|
237
|
+
bool local_LoadFullScreenFromConfigs()
|
238
|
+
{
|
239
|
+
ID fsc = rb_intern("FullScreen");
|
240
|
+
if(rb_const_defined(rb_mConfig, fsc))
|
241
|
+
return RTEST(rb_const_get(rb_mConfig, fsc));
|
242
|
+
return false;
|
243
|
+
}
|
244
|
+
|
245
|
+
void local_LoadSmoothScreenFromConfigs()
|
246
|
+
{
|
247
|
+
ID fsc = rb_intern("SmoothScreen");
|
248
|
+
if(rb_const_defined(rb_mConfig, fsc))
|
249
|
+
SmoothScreen = RTEST(rb_const_get(rb_mConfig, fsc));
|
250
|
+
else
|
251
|
+
SmoothScreen = false;
|
252
|
+
}
|
253
|
+
|
254
|
+
void local_Graphics_TransitionBasic(VALUE self, long time)
|
255
|
+
{
|
256
|
+
RGSSTransition = false;
|
257
|
+
sf::Color freeze_color(255, 255, 225, 255);
|
258
|
+
for (long i = 1; i <= time; i++)
|
259
|
+
{
|
260
|
+
freeze_color.a = 255 * (time - i) / time;
|
261
|
+
Graphics_freeze_sprite->setColor(freeze_color);
|
262
|
+
rb_Graphics_update(self);
|
263
|
+
}
|
264
|
+
}
|
265
|
+
|
266
|
+
void local_Graphics_TransitionRGSS(VALUE self, long time, VALUE bitmap)
|
267
|
+
{
|
268
|
+
Graphics_freeze_sprite->setColor(sf::Color(255, 255, 255, 255));
|
269
|
+
RGSSTransition = true;
|
270
|
+
Graphics_freeze_shader->setUniform("transition", *rb_Bitmap_getTexture(bitmap));
|
271
|
+
for (long i = 1; i <= time; i++)
|
272
|
+
{
|
273
|
+
Graphics_freeze_shader->setUniform("param", static_cast<float>(i) / time);
|
274
|
+
rb_Graphics_update(self);
|
275
|
+
}
|
276
|
+
}
|
277
|
+
|
278
|
+
const std::string GraphicsTransitionFragmentShader = \
|
279
|
+
"uniform float param;" \
|
280
|
+
"uniform sampler2D texture;" \
|
281
|
+
"uniform sampler2D transition;" \
|
282
|
+
"const float sensibilite = 0.05;" \
|
283
|
+
"const float scale = 1.0 + sensibilite;" \
|
284
|
+
"void main()" \
|
285
|
+
"{" \
|
286
|
+
" vec4 frag = texture2D(texture, gl_TexCoord[0].xy);" \
|
287
|
+
" vec4 tran = texture2D(transition, gl_TexCoord[0].xy);" \
|
288
|
+
" float pixel = max(max(tran.r, tran.g), tran.b);" \
|
289
|
+
" pixel -= (param * scale);" \
|
290
|
+
" if(pixel < sensibilite)" \
|
291
|
+
" {" \
|
292
|
+
" frag.a = max(0.0, sensibilite + pixel / sensibilite);" \
|
293
|
+
" }" \
|
294
|
+
" gl_FragColor = frag;" \
|
295
|
+
"}";
|
296
|
+
|
297
|
+
void local_Graphics_LoadShader()
|
298
|
+
{
|
299
|
+
Graphics_freeze_shader = new sf::Shader();
|
300
|
+
Graphics_freeze_shader->loadFromMemory(GraphicsTransitionFragmentShader, sf::Shader::Type::Fragment);
|
301
|
+
}
|
302
|
+
|
303
|
+
void local_Graphics_Take_Snapshot(sf::Texture* text)
|
304
|
+
{
|
305
|
+
sf::Vector2u sc_sz = game_window->getSize();
|
306
|
+
int x = 0;
|
307
|
+
int y = 0;
|
308
|
+
int sw = ScreenWidth * Graphics_Scale;
|
309
|
+
int sh = ScreenHeight * Graphics_Scale;
|
310
|
+
if(sc_sz.x < sw)
|
311
|
+
{
|
312
|
+
x = sw - sc_sz.x;
|
313
|
+
}
|
314
|
+
else
|
315
|
+
sw = sc_sz.x;
|
316
|
+
if(sc_sz.y < sh)
|
317
|
+
{
|
318
|
+
y = sh - sc_sz.y;
|
319
|
+
}
|
320
|
+
else
|
321
|
+
sh = sc_sz.y;
|
322
|
+
text->create(sw, sh);
|
323
|
+
text->update(*game_window, x, y);
|
324
|
+
}
|
325
|
+
|
326
|
+
void local_Graphics_initRender()
|
327
|
+
{
|
328
|
+
if (Graphics_Render == nullptr && Graphics_States != nullptr)
|
329
|
+
{
|
330
|
+
Graphics_Render = new sf::RenderTexture();
|
331
|
+
Graphics_Render->create(ScreenWidth, ScreenHeight);
|
332
|
+
}
|
333
|
+
}
|
334
|
+
|
335
|
+
VALUE local_Graphics_Dispose_Bitmap(VALUE block_arg, VALUE data, int argc, VALUE* argv)
|
336
|
+
{
|
337
|
+
if(RDATA(block_arg)->data != nullptr)
|
338
|
+
rb_Bitmap_Dispose(block_arg);
|
339
|
+
}
|
340
|
+
|
341
|
+
void local_Graphics_Clear_Stack()
|
342
|
+
{
|
343
|
+
//std::cout << "CLEAN STACK" << std::endl;
|
344
|
+
VALUE table = rb_ivar_get(rb_mGraphics, rb_iElementTable);
|
345
|
+
long sz = RARRAY_LEN(table);
|
346
|
+
VALUE* ori = RARRAY_PTR(table);
|
347
|
+
/* Disposing each Sprite/Viewport/Text */
|
348
|
+
for(long i = 0; i < sz; i++)
|
349
|
+
{
|
350
|
+
if(rb_obj_is_kind_of(ori[i], rb_cViewport) == Qtrue)
|
351
|
+
{
|
352
|
+
if(RDATA(ori[i])->data != nullptr)
|
353
|
+
rb_Viewport_Dispose(ori[i]);
|
354
|
+
}
|
355
|
+
else if(rb_obj_is_kind_of(ori[i], rb_cSprite) == Qtrue)
|
356
|
+
rb_Sprite_DisposeFromViewport(ori[i]);
|
357
|
+
else if(rb_obj_is_kind_of(ori[i], rb_cText) == Qtrue)
|
358
|
+
rb_Text_DisposeFromViewport(ori[i]);
|
359
|
+
}
|
360
|
+
rb_ary_clear(table);
|
361
|
+
/* Disposing each Bitmap */
|
362
|
+
rb_block_call(rb_const_get(rb_cObject, rb_intern("ObjectSpace")), rb_intern("each_object"), 1, &rb_cBitmap,
|
363
|
+
(rb_block_call_func_t)local_Graphics_Dispose_Bitmap, Qnil);
|
364
|
+
rb_gc_start();
|
365
|
+
}
|
@@ -0,0 +1,37 @@
|
|
1
|
+
#ifndef L_GRAPHICS_LOCAL_H
|
2
|
+
#define L_GRAPHICS_LOCAL_H
|
3
|
+
#include "LiteRGSS.h"
|
4
|
+
|
5
|
+
struct GraphicUpdateMessage {
|
6
|
+
VALUE errorObject;
|
7
|
+
const char* message;
|
8
|
+
};
|
9
|
+
|
10
|
+
void local_LoadVideoModeFromConfigs(sf::VideoMode& vmode);
|
11
|
+
const sf::String local_LoadTitleFromConfigs();
|
12
|
+
unsigned int local_LoadFrameRateFromConfigs();
|
13
|
+
bool local_LoadVSYNCFromConfigs();
|
14
|
+
bool local_LoadFullScreenFromConfigs();
|
15
|
+
void local_LoadSmoothScreenFromConfigs();
|
16
|
+
void* local_Graphics_Update_Internal(void* data);
|
17
|
+
VALUE local_Graphics_Update_RaiseError(VALUE self, GraphicUpdateMessage* message);
|
18
|
+
void local_Graphics_Update_Process_Event(GraphicUpdateMessage*& message);
|
19
|
+
void local_Graphics_Update_Draw(std::vector<CDrawable_Element*>* stack);
|
20
|
+
void local_Graphics_Take_Snapshot(sf::Texture* text);
|
21
|
+
void local_Graphics_Clear_Stack();
|
22
|
+
void local_Graphics_TransitionBasic(VALUE self, long time);
|
23
|
+
void local_Graphics_TransitionRGSS(VALUE self, long time, VALUE bitmap);
|
24
|
+
void local_Graphics_LoadShader();
|
25
|
+
void local_Graphics_DrawBrightness();
|
26
|
+
void local_Graphics_initRender();
|
27
|
+
|
28
|
+
extern sf::RenderWindow* game_window;
|
29
|
+
extern bool InsideGraphicsUpdate;
|
30
|
+
extern sf::Texture* Graphics_freeze_texture;
|
31
|
+
extern sf::Sprite* Graphics_freeze_sprite;
|
32
|
+
extern sf::Shader* Graphics_freeze_shader;
|
33
|
+
extern unsigned char Graphics_Brightness;
|
34
|
+
extern sf::RenderTexture* Graphics_Render;
|
35
|
+
extern sf::RenderStates* Graphics_States;
|
36
|
+
|
37
|
+
#endif
|
@@ -0,0 +1,460 @@
|
|
1
|
+
#include "LiteRGSS.h"
|
2
|
+
#include "CBitmap_Element.h"
|
3
|
+
#include "CRect_Element.h"
|
4
|
+
|
5
|
+
VALUE rb_cImage = Qnil;
|
6
|
+
|
7
|
+
#define IMAGE_PROTECT if(RDATA(self)->data == nullptr) \
|
8
|
+
{\
|
9
|
+
rb_raise(rb_eRGSSError, "Disposed Image."); \
|
10
|
+
}
|
11
|
+
|
12
|
+
#define GET_IMAGE sf::Image* img; \
|
13
|
+
Data_Get_Struct(self, sf::Image, img); \
|
14
|
+
IMAGE_PROTECT \
|
15
|
+
|
16
|
+
void rb_Image_Free(void* data)
|
17
|
+
{
|
18
|
+
sf::Image* img = reinterpret_cast<sf::Image*>(data);
|
19
|
+
if(img != nullptr)
|
20
|
+
{
|
21
|
+
delete img;
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
VALUE rb_Image_Alloc(VALUE klass)
|
26
|
+
{
|
27
|
+
sf::Image* img = new sf::Image();
|
28
|
+
return Data_Wrap_Struct(klass, NULL, rb_Image_Free, img);
|
29
|
+
}
|
30
|
+
|
31
|
+
void Init_Image()
|
32
|
+
{
|
33
|
+
rb_cImage = rb_define_class_under(rb_mLiteRGSS, "Image", rb_cObject);
|
34
|
+
rb_define_alloc_func(rb_cImage, rb_Image_Alloc);
|
35
|
+
rb_define_method(rb_cImage, "initialize", _rbf rb_Image_Initialize, -1);
|
36
|
+
rb_define_method(rb_cImage, "initialize_copy", _rbf rb_Image_Initialize_Copy, 1);
|
37
|
+
rb_define_method(rb_cImage, "dispose", _rbf rb_Image_Dispose, 0);
|
38
|
+
rb_define_method(rb_cImage, "disposed?", _rbf rb_Image_Disposed, 0);
|
39
|
+
rb_define_method(rb_cImage, "width", _rbf rb_Image_Width, 0);
|
40
|
+
rb_define_method(rb_cImage, "height", _rbf rb_Image_Height, 0);
|
41
|
+
rb_define_method(rb_cImage, "rect", _rbf rb_Image_Rect, 0);
|
42
|
+
rb_define_method(rb_cImage, "copy_to_bitmap", _rbf rb_Image_Copy_to_Bitmap, 1);
|
43
|
+
rb_define_method(rb_cImage, "blt", _rbf rb_Image_blt, 4);
|
44
|
+
rb_define_method(rb_cImage, "blt!", _rbf rb_Image_blt_fast, 4);
|
45
|
+
rb_define_method(rb_cImage, "stretch_blt", _rbf rb_Image_stretch_blt, 3);
|
46
|
+
rb_define_method(rb_cImage, "stretch_blt!", _rbf rb_Image_stretch_blt_fast, 3);
|
47
|
+
rb_define_method(rb_cImage, "get_pixel", _rbf rb_Image_get_pixel, 2);
|
48
|
+
rb_define_method(rb_cImage, "get_pixel_alpha", _rbf rb_Image_get_pixel_alpha, 2);
|
49
|
+
rb_define_method(rb_cImage, "set_pixel", _rbf rb_Image_set_pixel, 3);
|
50
|
+
rb_define_method(rb_cImage, "clear_rect", _rbf rb_Image_clear_rect, 4);
|
51
|
+
rb_define_method(rb_cImage, "fill_rect", _rbf rb_Image_fill_rect, 5);
|
52
|
+
rb_define_method(rb_cImage, "create_mask", _rbf rb_Image_create_mask, 2);
|
53
|
+
rb_define_method(rb_cImage, "to_png", _rbf rb_Image_toPNG, 0);
|
54
|
+
rb_define_method(rb_cImage, "to_png_file", _rbf rb_Image_toPNG_file, 1);
|
55
|
+
}
|
56
|
+
|
57
|
+
VALUE rb_Image_Initialize(int argc, VALUE *argv, VALUE self)
|
58
|
+
{
|
59
|
+
VALUE string, fromMemory;
|
60
|
+
GET_IMAGE
|
61
|
+
rb_scan_args(argc, argv, "11", &string, &fromMemory);
|
62
|
+
/* Load From filename */
|
63
|
+
if(NIL_P(fromMemory))
|
64
|
+
{
|
65
|
+
rb_check_type(string, T_STRING);
|
66
|
+
if(!rb_Image_LoadLodePNG(img, RSTRING_PTR(string), 0))
|
67
|
+
if(!img->loadFromFile(RSTRING_PTR(string)))
|
68
|
+
{
|
69
|
+
errno = ENOENT;
|
70
|
+
rb_sys_fail(RSTRING_PTR(string));
|
71
|
+
}
|
72
|
+
}
|
73
|
+
/* Load From Memory */
|
74
|
+
else if(fromMemory == Qtrue)
|
75
|
+
{
|
76
|
+
rb_check_type(string, T_STRING);
|
77
|
+
if(!rb_Image_LoadLodePNG(img, RSTRING_PTR(string), RSTRING_LEN(string)))
|
78
|
+
if(!img->loadFromMemory(RSTRING_PTR(string), RSTRING_LEN(string)))
|
79
|
+
rb_raise(rb_eRGSSError, "Failed to load image from memory.");
|
80
|
+
}
|
81
|
+
else
|
82
|
+
{
|
83
|
+
rb_check_type(string, T_FIXNUM);
|
84
|
+
rb_check_type(fromMemory, T_FIXNUM);
|
85
|
+
img->create(rb_num2long(string), rb_num2long(fromMemory), sf::Color(0, 0, 0, 0));
|
86
|
+
//rb_raise(rb_eRGSSError, "Bitmap no longer allow drawing, thus Bitmap.new(width, height) is not allowed.");
|
87
|
+
}
|
88
|
+
return self;
|
89
|
+
}
|
90
|
+
|
91
|
+
VALUE rb_Image_Initialize_Copy(VALUE self, VALUE other)
|
92
|
+
{
|
93
|
+
//rb_notimplement();
|
94
|
+
rb_check_frozen(self);
|
95
|
+
if(rb_obj_is_kind_of(other, rb_cImage) != Qtrue)
|
96
|
+
{
|
97
|
+
rb_raise(rb_eTypeError, "Cannot clone %s into Image.", RSTRING_PTR(rb_class_name(CLASS_OF(other))));
|
98
|
+
return self;
|
99
|
+
}
|
100
|
+
sf::Image* img;
|
101
|
+
sf::Image* imgo;
|
102
|
+
Data_Get_Struct(self, sf::Image, img);
|
103
|
+
Data_Get_Struct(other, sf::Image, imgo);
|
104
|
+
if(imgo == nullptr)
|
105
|
+
rb_raise(rb_eRGSSError, "Disposed Image.");
|
106
|
+
img->create(imgo->getSize().x, imgo->getSize().y, imgo->getPixelsPtr());
|
107
|
+
return self;
|
108
|
+
}
|
109
|
+
|
110
|
+
VALUE rb_Image_Dispose(VALUE self)
|
111
|
+
{
|
112
|
+
GET_IMAGE
|
113
|
+
delete img;
|
114
|
+
RDATA(self)->data = nullptr;
|
115
|
+
return self;
|
116
|
+
}
|
117
|
+
|
118
|
+
VALUE rb_Image_Disposed(VALUE self)
|
119
|
+
{
|
120
|
+
rb_check_type(self, T_DATA);
|
121
|
+
return (RDATA(self)->data == nullptr ? Qtrue : Qfalse);
|
122
|
+
}
|
123
|
+
|
124
|
+
VALUE rb_Image_Width(VALUE self)
|
125
|
+
{
|
126
|
+
GET_IMAGE
|
127
|
+
sf::Vector2u size = img->getSize();
|
128
|
+
return rb_int2inum(size.x);
|
129
|
+
}
|
130
|
+
|
131
|
+
VALUE rb_Image_Height(VALUE self)
|
132
|
+
{
|
133
|
+
GET_IMAGE
|
134
|
+
sf::Vector2u size = img->getSize();
|
135
|
+
return rb_int2inum(size.y);
|
136
|
+
}
|
137
|
+
|
138
|
+
VALUE rb_Image_Rect(VALUE self)
|
139
|
+
{
|
140
|
+
GET_IMAGE
|
141
|
+
sf::Vector2u size = img->getSize();
|
142
|
+
VALUE argv[4] = {LONG2FIX(0), LONG2FIX(0), rb_int2inum(size.x), rb_int2inum(size.y)};
|
143
|
+
return rb_class_new_instance(4, argv, rb_cRect);
|
144
|
+
}
|
145
|
+
|
146
|
+
VALUE rb_Image_Copy_to_Bitmap(VALUE self, VALUE bitmap)
|
147
|
+
{
|
148
|
+
GET_IMAGE
|
149
|
+
rb_Bitmap_getTexture(bitmap)->update(*img);
|
150
|
+
return self;
|
151
|
+
}
|
152
|
+
|
153
|
+
VALUE rb_Image_blt_fast(VALUE self, VALUE x, VALUE y, VALUE src_image, VALUE rect)
|
154
|
+
{
|
155
|
+
GET_IMAGE
|
156
|
+
sf::Image* img2 = rb_Image_get_image(src_image);
|
157
|
+
CRect_Element* s_rect = rb_Rect_get_rect(rect);
|
158
|
+
img->copy(
|
159
|
+
*img2,
|
160
|
+
NUM2ULONG(x),
|
161
|
+
NUM2ULONG(y),
|
162
|
+
*s_rect->getRect()
|
163
|
+
);
|
164
|
+
return self;
|
165
|
+
}
|
166
|
+
|
167
|
+
VALUE rb_Image_blt(VALUE self, VALUE x, VALUE y, VALUE src_image, VALUE rect)
|
168
|
+
{
|
169
|
+
GET_IMAGE
|
170
|
+
sf::Image* img2 = rb_Image_get_image(src_image);
|
171
|
+
CRect_Element* s_rect = rb_Rect_get_rect(rect);
|
172
|
+
img->copy(
|
173
|
+
*img2,
|
174
|
+
NUM2ULONG(x),
|
175
|
+
NUM2ULONG(y),
|
176
|
+
*s_rect->getRect(),
|
177
|
+
true
|
178
|
+
);
|
179
|
+
return self;
|
180
|
+
}
|
181
|
+
|
182
|
+
VALUE rb_Image_clear_rect(VALUE self, VALUE x, VALUE y, VALUE width, VALUE height)
|
183
|
+
{
|
184
|
+
GET_IMAGE
|
185
|
+
rb_check_type(x, T_FIXNUM);
|
186
|
+
rb_check_type(y, T_FIXNUM);
|
187
|
+
rb_check_type(width, T_FIXNUM);
|
188
|
+
rb_check_type(height, T_FIXNUM);
|
189
|
+
long x1 = NUM2LONG(x);
|
190
|
+
long x2 = NUM2LONG(width) + x1;
|
191
|
+
if (x1 < 0)
|
192
|
+
x1 = 0;
|
193
|
+
long y1 = NUM2LONG(y);
|
194
|
+
long y2 = NUM2LONG(height) + y1;
|
195
|
+
if (y1 < 0)
|
196
|
+
y1 = 0;
|
197
|
+
sf::Color clr = sf::Color(0, 0, 0, 0);
|
198
|
+
while (y1 < y2)
|
199
|
+
{
|
200
|
+
for (long x3 = x1; x3 < x2; x3++)
|
201
|
+
img->setPixel(x3, y1, clr);
|
202
|
+
y1++;
|
203
|
+
}
|
204
|
+
return self;
|
205
|
+
}
|
206
|
+
|
207
|
+
VALUE rb_Image_fill_rect(VALUE self, VALUE x, VALUE y, VALUE width, VALUE height, VALUE color)
|
208
|
+
{
|
209
|
+
GET_IMAGE;
|
210
|
+
if (rb_obj_is_kind_of(color, rb_cColor) != Qtrue)
|
211
|
+
return self;
|
212
|
+
sf::Color* rcolor;
|
213
|
+
Data_Get_Struct(color, sf::Color, rcolor);
|
214
|
+
rb_check_type(x, T_FIXNUM);
|
215
|
+
rb_check_type(y, T_FIXNUM);
|
216
|
+
rb_check_type(width, T_FIXNUM);
|
217
|
+
rb_check_type(height, T_FIXNUM);
|
218
|
+
long x1 = NUM2LONG(x);
|
219
|
+
long x2 = NUM2LONG(width) + x1;
|
220
|
+
if (x1 < 0)
|
221
|
+
x1 = 0;
|
222
|
+
long y1 = NUM2LONG(y);
|
223
|
+
long y2 = NUM2LONG(height) + y1;
|
224
|
+
if (y1 < 0)
|
225
|
+
y1 = 0;
|
226
|
+
while (y1 < y2)
|
227
|
+
{
|
228
|
+
for (long x3 = x1; x3 < x2; x3++)
|
229
|
+
img->setPixel(x3, y1, *rcolor);
|
230
|
+
y1++;
|
231
|
+
}
|
232
|
+
return self;
|
233
|
+
}
|
234
|
+
|
235
|
+
VALUE rb_Image_toPNG(VALUE self)
|
236
|
+
{
|
237
|
+
GET_IMAGE;
|
238
|
+
unsigned char* out;
|
239
|
+
size_t size;
|
240
|
+
if (lodepng_encode32(&out, &size, img->getPixelsPtr(), img->getSize().x, img->getSize().y) != 0)
|
241
|
+
{
|
242
|
+
if (out)
|
243
|
+
free(out);
|
244
|
+
return Qnil;
|
245
|
+
}
|
246
|
+
VALUE ret_val = rb_str_new(reinterpret_cast<const char*>(out), size);
|
247
|
+
free(out);
|
248
|
+
return ret_val;
|
249
|
+
}
|
250
|
+
|
251
|
+
VALUE rb_Image_toPNG_file(VALUE self, VALUE filename)
|
252
|
+
{
|
253
|
+
rb_check_type(filename, T_STRING);
|
254
|
+
GET_IMAGE;
|
255
|
+
if (lodepng_encode32_file(RSTRING_PTR(filename), img->getPixelsPtr(), img->getSize().x, img->getSize().y) != 0)
|
256
|
+
return Qfalse;
|
257
|
+
return Qtrue;
|
258
|
+
}
|
259
|
+
|
260
|
+
VALUE rb_Image_get_pixel(VALUE self, VALUE x, VALUE y)
|
261
|
+
{
|
262
|
+
GET_IMAGE;
|
263
|
+
unsigned long px = NUM2ULONG(x);
|
264
|
+
unsigned long py = NUM2ULONG(y);
|
265
|
+
sf::Vector2u size = img->getSize();
|
266
|
+
if (px < size.x && py < size.y)
|
267
|
+
{
|
268
|
+
sf::Color color = img->getPixel(px, py);
|
269
|
+
VALUE argv[4] = { LONG2FIX(color.r), LONG2FIX(color.g), LONG2FIX(color.b), LONG2FIX(color.a) };
|
270
|
+
return rb_class_new_instance(4, argv, rb_cColor);
|
271
|
+
}
|
272
|
+
return Qnil;
|
273
|
+
}
|
274
|
+
|
275
|
+
VALUE rb_Image_get_pixel_alpha(VALUE self, VALUE x, VALUE y)
|
276
|
+
{
|
277
|
+
GET_IMAGE;
|
278
|
+
unsigned long px = NUM2ULONG(x);
|
279
|
+
unsigned long py = NUM2ULONG(y);
|
280
|
+
sf::Vector2u size = img->getSize();
|
281
|
+
if (px < size.x && py < size.y)
|
282
|
+
{
|
283
|
+
sf::Color color = img->getPixel(px, py);
|
284
|
+
return LONG2FIX(color.a);
|
285
|
+
}
|
286
|
+
return LONG2FIX(0);
|
287
|
+
}
|
288
|
+
|
289
|
+
VALUE rb_Image_set_pixel(VALUE self, VALUE x, VALUE y, VALUE color)
|
290
|
+
{
|
291
|
+
GET_IMAGE;
|
292
|
+
unsigned long px = NUM2ULONG(x);
|
293
|
+
unsigned long py = NUM2ULONG(y);
|
294
|
+
sf::Vector2u size = img->getSize();
|
295
|
+
if (px < size.x && py < size.y)
|
296
|
+
{
|
297
|
+
sf::Color* color2 = rb_Color_get_color(color);
|
298
|
+
Data_Get_Struct(color, sf::Color, color2);
|
299
|
+
if(color2 != nullptr)
|
300
|
+
img->setPixel(px, py, *color2);
|
301
|
+
}
|
302
|
+
return self;
|
303
|
+
}
|
304
|
+
|
305
|
+
VALUE rb_Image_stretch_blt_fast(VALUE self, VALUE dest_rect, VALUE src_image, VALUE src_rect)
|
306
|
+
{
|
307
|
+
GET_IMAGE;
|
308
|
+
CRect_Element* dst_rc = rb_Rect_get_rect(dest_rect);
|
309
|
+
CRect_Element* src_rc = rb_Rect_get_rect(src_rect);
|
310
|
+
sf::Image* src_img = rb_Image_get_image(src_image);
|
311
|
+
int s_w = src_rc->getRect()->width;
|
312
|
+
int d_w = dst_rc->getRect()->width;
|
313
|
+
int s_h = src_rc->getRect()->height;
|
314
|
+
int d_h = dst_rc->getRect()->height;
|
315
|
+
int os_x = src_rc->getRect()->left;
|
316
|
+
int os_y = src_rc->getRect()->top;
|
317
|
+
int od_x = dst_rc->getRect()->left;
|
318
|
+
int od_y = dst_rc->getRect()->top;
|
319
|
+
sf::Vector2u simg_size = src_img->getSize();
|
320
|
+
sf::Vector2u dimg_size = img->getSize();
|
321
|
+
int s_x, s_y, d_x, d_y;
|
322
|
+
for (int y = 0; y < d_h; y++)
|
323
|
+
{
|
324
|
+
d_y = y + od_y;
|
325
|
+
if (d_y >= dimg_size.y)
|
326
|
+
break;
|
327
|
+
if (d_y < 0)
|
328
|
+
continue;
|
329
|
+
s_y = y * s_h / d_h + os_y;
|
330
|
+
if (s_y >= simg_size.y)
|
331
|
+
break;
|
332
|
+
if (s_y < 0)
|
333
|
+
continue;
|
334
|
+
for (int x = 0; x < d_w; x++)
|
335
|
+
{
|
336
|
+
d_x = x + od_x;
|
337
|
+
if (d_x >= dimg_size.x)
|
338
|
+
break;
|
339
|
+
if (d_x < 0)
|
340
|
+
continue;
|
341
|
+
s_x = x * s_w / d_w + os_x;
|
342
|
+
if (s_x >= simg_size.x)
|
343
|
+
break;
|
344
|
+
if (s_x < 0)
|
345
|
+
continue;
|
346
|
+
img->setPixel(d_x, d_y, src_img->getPixel(s_x, s_y));
|
347
|
+
}
|
348
|
+
}
|
349
|
+
return self;
|
350
|
+
}
|
351
|
+
|
352
|
+
VALUE rb_Image_stretch_blt(VALUE self, VALUE dest_rect, VALUE src_image, VALUE src_rect)
|
353
|
+
{
|
354
|
+
GET_IMAGE;
|
355
|
+
CRect_Element* dst_rc = rb_Rect_get_rect(dest_rect);
|
356
|
+
CRect_Element* src_rc = rb_Rect_get_rect(src_rect);
|
357
|
+
sf::Image* src_img = rb_Image_get_image(src_image);
|
358
|
+
sf::Color src, dest;
|
359
|
+
int s_w = src_rc->getRect()->width;
|
360
|
+
int d_w = dst_rc->getRect()->width;
|
361
|
+
int s_h = src_rc->getRect()->height;
|
362
|
+
int d_h = dst_rc->getRect()->height;
|
363
|
+
int os_x = src_rc->getRect()->left;
|
364
|
+
int os_y = src_rc->getRect()->top;
|
365
|
+
int od_x = dst_rc->getRect()->left;
|
366
|
+
int od_y = dst_rc->getRect()->top;
|
367
|
+
sf::Vector2u simg_size = src_img->getSize();
|
368
|
+
sf::Vector2u dimg_size = img->getSize();
|
369
|
+
int s_x, s_y, d_x, d_y;
|
370
|
+
unsigned char mina;
|
371
|
+
for (int y = 0; y < d_h; y++)
|
372
|
+
{
|
373
|
+
d_y = y + od_y;
|
374
|
+
if (d_y >= dimg_size.y)
|
375
|
+
break;
|
376
|
+
if (d_y < 0)
|
377
|
+
continue;
|
378
|
+
s_y = y * s_h / d_h + os_y;
|
379
|
+
if (s_y >= simg_size.y)
|
380
|
+
break;
|
381
|
+
if (s_y < 0)
|
382
|
+
continue;
|
383
|
+
for (int x = 0; x < d_w; x++)
|
384
|
+
{
|
385
|
+
d_x = x + od_x;
|
386
|
+
if (d_x >= dimg_size.x)
|
387
|
+
break;
|
388
|
+
if (d_x < 0)
|
389
|
+
continue;
|
390
|
+
s_x = x * s_w / d_w + os_x;
|
391
|
+
if (s_x >= simg_size.x)
|
392
|
+
break;
|
393
|
+
if (s_x < 0)
|
394
|
+
continue;
|
395
|
+
src = src_img->getPixel(s_x, s_y);
|
396
|
+
dest = img->getPixel(d_x, d_y);
|
397
|
+
if(dest.a > 0)
|
398
|
+
{
|
399
|
+
mina = 255 - src.a;
|
400
|
+
src.r = (src.r * src.a + dest.r * mina) / 255;
|
401
|
+
src.g = (src.g * src.a + dest.g * mina) / 255;
|
402
|
+
src.b = (src.b * src.a + dest.b * mina) / 255;
|
403
|
+
src.a += (dest.a * mina / 255);
|
404
|
+
}
|
405
|
+
img->setPixel(d_x, d_y, src);
|
406
|
+
}
|
407
|
+
}
|
408
|
+
return self;
|
409
|
+
}
|
410
|
+
|
411
|
+
VALUE rb_Image_create_mask(VALUE self, VALUE color, VALUE alpha)
|
412
|
+
{
|
413
|
+
GET_IMAGE;
|
414
|
+
sf::Color* col = rb_Color_get_color(color);
|
415
|
+
img->createMaskFromColor(*col, NUM2ULONG(alpha));
|
416
|
+
return self;
|
417
|
+
}
|
418
|
+
|
419
|
+
sf::Image* rb_Image_get_image(VALUE self)
|
420
|
+
{
|
421
|
+
rb_Image_test_image(self);
|
422
|
+
GET_IMAGE;
|
423
|
+
return img;
|
424
|
+
}
|
425
|
+
|
426
|
+
void rb_Image_test_image(VALUE self)
|
427
|
+
{
|
428
|
+
if (rb_obj_is_kind_of(self, rb_cImage) != Qtrue)
|
429
|
+
{
|
430
|
+
rb_raise(rb_eTypeError, "Expected Image got %s.", RSTRING_PTR(rb_class_name(CLASS_OF(self))));
|
431
|
+
}
|
432
|
+
}
|
433
|
+
|
434
|
+
bool rb_Image_LoadLodePNG(sf::Image* img, char* str, long from_memory_size)
|
435
|
+
{
|
436
|
+
unsigned char* out = nullptr;
|
437
|
+
unsigned w;
|
438
|
+
unsigned h;
|
439
|
+
if (from_memory_size > 0)
|
440
|
+
{
|
441
|
+
if (lodepng_decode32(&out, &w, &h, reinterpret_cast<unsigned char*>(str), from_memory_size) != 0)
|
442
|
+
{
|
443
|
+
if (out)
|
444
|
+
free(out);
|
445
|
+
return false;
|
446
|
+
}
|
447
|
+
}
|
448
|
+
else
|
449
|
+
{
|
450
|
+
if (lodepng_decode32_file(&out, &w, &h, str) != 0)
|
451
|
+
{
|
452
|
+
if (out)
|
453
|
+
free(out);
|
454
|
+
return false;
|
455
|
+
}
|
456
|
+
}
|
457
|
+
img->create(w, h, reinterpret_cast<sf::Uint8*>(out));
|
458
|
+
free(out);
|
459
|
+
return true;
|
460
|
+
}
|