]> git.localhorst.tv Git - l2e.git/blob - src/graphics/Frame.cpp
dbfd814067c95668860d6e34107684a06636e748
[l2e.git] / src / graphics / Frame.cpp
1 #include "Frame.h"
2
3 #include "Texture.h"
4 #include "../loader/Interpreter.h"
5 #include "../loader/TypeDescription.h"
6
7 using geometry::Vector;
8 using loader::FieldDescription;
9 using loader::Interpreter;
10 using loader::TypeDescription;
11
12 namespace graphics {
13
14 // TODO: maybe create a cache for frames?
15 void Frame::Draw(SDL_Surface *dest, const Vector<int> &position, int width, int height) const {
16         if (!surface) {
17                 SDL_Rect rect;
18                 rect.x = position.X();
19                 rect.y = position.Y();
20                 rect.w = width;
21                 rect.h = height;
22                 SDL_FillRect(dest, &rect, SDL_MapRGB(dest->format, 0xFF, 0x00, 0x00));
23                 return;
24         }
25         // top-left corner
26         SDL_Rect srcRect;
27         srcRect.x = offset.X();
28         srcRect.y = offset.Y();
29         srcRect.w = BorderWidth();
30         srcRect.h = BorderHeight();
31         SDL_Rect destRect;
32         destRect.x = position.X();
33         destRect.y = position.Y();
34         SDL_BlitSurface(surface, &srcRect, dest, &destRect);
35
36         // top border
37         Texture(surface, Vector<int>(RepeatWidth(), BorderHeight()), Vector<int>(offset.X() + BorderWidth(), offset.Y()))
38         .Render(dest, Vector<int>(position.X() + BorderWidth(), position.Y()), Vector<int>(position.X() + width - BorderWidth(), position.Y() + BorderHeight()));
39
40         // top-right corner
41         srcRect.x = offset.X() + RepeatWidth() + BorderWidth();
42         srcRect.w = BorderWidth();
43         destRect.x = position.X() + width - BorderWidth();
44         SDL_BlitSurface(surface, &srcRect, dest, &destRect);
45
46         // left border
47         Texture(surface, Vector<int>(BorderWidth(), RepeatHeight()), Vector<int>(offset.X(), offset.Y() + BorderHeight()))
48         .Render(dest, Vector<int>(position.X(), position.Y() + BorderHeight()), Vector<int>(position.X() + BorderWidth(), position.Y() + height - BorderHeight()));
49
50         // center fill
51         Texture(surface, RepeatSize(), Vector<int>(offset.X() + BorderWidth(), offset.Y() + BorderHeight()))
52         .Render(dest, position + BorderSize(), position + Vector<int>(width, height) - BorderSize());
53
54         // right border
55         Texture(surface, Vector<int>(BorderWidth(), RepeatHeight()), Vector<int>(offset.X() + BorderWidth() + RepeatWidth(), offset.Y() + BorderHeight()))
56         .Render(dest, Vector<int>(position.X() + width - BorderWidth(), position.Y() + BorderHeight()), Vector<int>(position.X() + width, position.Y() + height - BorderHeight()));
57
58         // bottom-left corner
59         srcRect.x = offset.X();
60         srcRect.y = offset.Y() + BorderHeight() + RepeatHeight();
61         srcRect.w = BorderWidth();
62         srcRect.h = BorderHeight();
63         destRect.x = position.X();
64         destRect.y = position.Y() + height - BorderHeight();
65         SDL_BlitSurface(surface, &srcRect, dest, &destRect);
66
67         // bottom border
68         Texture(surface, Vector<int>(RepeatWidth(), BorderHeight()), Vector<int>(offset.X() + BorderWidth(), offset.Y() + BorderHeight() + RepeatHeight()))
69         .Render(dest, Vector<int>(position.X() + BorderWidth(), position.Y() + height - BorderHeight()), Vector<int>(position.X() + width - BorderWidth(), position.Y() + height));
70
71         // bottom-right corner
72         srcRect.x = offset.X() + BorderWidth() + RepeatWidth();
73         srcRect.w = BorderWidth();
74         destRect.x = position.X() + width - BorderWidth();
75         SDL_BlitSurface(surface, &srcRect, dest, &destRect);
76 }
77
78
79 void Frame::CreateTypeDescription() {
80         Frame f;
81
82         TypeDescription &td(TypeDescription::Create(TYPE_ID, "Frame"));
83         td.SetDescription(
84                         "A frame is basically a border + a background texture.\n"
85                         "It splits an image into 3*3 parts where the edges are kept as is and the sides and the middle part are repeated as needed.");
86         td.SetConstructor(&Construct);
87         td.SetSize(sizeof(Frame));
88
89         td.AddField("image", FieldDescription(((char *)&f.surface) - ((char *)&f), Interpreter::IMAGE_ID).SetReferenced().SetDescription("the underlying graphic from which the frame parts are cut"));
90         td.AddField("border", FieldDescription(((char *)&f.borderSize) - ((char *)&f), Interpreter::VECTOR_ID).SetDescription("size of the border part, dimensions of top-left corner"));
91         td.AddField("repeat", FieldDescription(((char *)&f.repeatSize) - ((char *)&f), Interpreter::VECTOR_ID).SetDescription("size of the repeat part, dimensions of a single tile of the background texture"));
92         td.AddField("offset", FieldDescription(((char *)&f.offset) - ((char *)&f), Interpreter::VECTOR_ID).SetDescription("offset into the image where to start cutting, coordinates of the top-left corner on the image"));
93 }
94
95 void Frame::Construct(void *data) {
96         new (data) Frame;
97 }
98
99 }