]> git.localhorst.tv Git - l2e.git/blob - src/graphics/Frame.cpp
removed now superfluous Application parameter to State callbacks
[l2e.git] / src / graphics / Frame.cpp
1 /*
2  * Frame.cpp
3  *
4  *  Created on: Aug 7, 2012
5  *      Author: holy
6  */
7
8 #include "Frame.h"
9
10 #include "../loader/TypeDescription.h"
11
12 using geometry::Vector;
13 using loader::FieldDescription;
14 using loader::TypeDescription;
15
16 namespace graphics {
17
18 // TODO: maybe create a cache for frames?
19 void Frame::Draw(SDL_Surface *dest, const Vector<int> &position, int width, int height) const {
20         if (!surface) {
21                 SDL_Rect rect;
22                 rect.x = position.X();
23                 rect.y = position.Y();
24                 rect.w = width;
25                 rect.h = height;
26                 SDL_FillRect(dest, &rect, SDL_MapRGB(dest->format, 0xFF, 0x00, 0x00));
27                 return;
28         }
29         // top-left corner
30         SDL_Rect srcRect;
31         srcRect.x = offset.X();
32         srcRect.y = offset.Y();
33         srcRect.w = BorderWidth();
34         srcRect.h = BorderHeight();
35         SDL_Rect destRect;
36         destRect.x = position.X();
37         destRect.y = position.Y();
38         SDL_BlitSurface(surface, &srcRect, dest, &destRect);
39
40         // top border
41         srcRect.x += BorderWidth();
42         srcRect.w = RepeatWidth();
43         destRect.x += BorderWidth();
44         int fullRepeatWidth(width - (2 * BorderWidth()));
45         int repeatCursor(0);
46         while (repeatCursor < fullRepeatWidth) {
47                 SDL_BlitSurface(surface, &srcRect, dest, &destRect);
48                 destRect.x += RepeatWidth();
49                 repeatCursor += RepeatWidth();
50         }
51
52         // top-right corner
53         srcRect.x += RepeatWidth();
54         srcRect.w = BorderWidth();
55         SDL_BlitSurface(surface, &srcRect, dest, &destRect);
56
57         // middle
58         destRect.y += BorderHeight();
59         int fullRepeatHeight(height - (2 * BorderHeight()));
60         int hRepeatCursor(0);
61         while (hRepeatCursor < fullRepeatHeight) {
62
63                 // left border
64                 srcRect.x = offset.X();
65                 srcRect.y = offset.Y() + BorderHeight();
66                 srcRect.w = BorderWidth();
67                 srcRect.h = RepeatHeight();
68                 destRect.x = position.X();
69                 SDL_BlitSurface(surface, &srcRect, dest, &destRect);
70
71                 // fill
72                 repeatCursor = 0;
73                 srcRect.x += BorderWidth();
74                 srcRect.w = RepeatWidth();
75                 destRect.x += BorderWidth();
76                 while (repeatCursor < fullRepeatWidth) {
77                         SDL_BlitSurface(surface, &srcRect, dest, &destRect);
78                         destRect.x += RepeatWidth();
79                         repeatCursor += RepeatWidth();
80                 }
81
82                 // right border
83                 srcRect.x += RepeatWidth();
84                 srcRect.w = BorderWidth();
85                 SDL_BlitSurface(surface, &srcRect, dest, &destRect);
86
87                 destRect.y += RepeatHeight();
88                 hRepeatCursor += RepeatHeight();
89         }
90
91         // bottom-left corner
92         srcRect.x = offset.X();
93         srcRect.y = offset.Y() + BorderHeight() + RepeatHeight();
94         srcRect.w = BorderWidth();
95         srcRect.h = BorderHeight();
96         destRect.x = position.X();
97         SDL_BlitSurface(surface, &srcRect, dest, &destRect);
98
99         // bottom border
100         srcRect.x += BorderWidth();
101         srcRect.w = RepeatWidth();
102         destRect.x += BorderWidth();
103         repeatCursor = 0;
104         while (repeatCursor < fullRepeatWidth) {
105                 SDL_BlitSurface(surface, &srcRect, dest, &destRect);
106                 destRect.x += RepeatWidth();
107                 repeatCursor += RepeatWidth();
108         }
109         if (fullRepeatWidth < fullRepeatWidth) {
110                 srcRect.w = fullRepeatWidth - fullRepeatWidth;
111                 SDL_BlitSurface(surface, &srcRect, dest, &destRect);
112                 destRect.x += fullRepeatWidth - fullRepeatWidth;
113         }
114
115         // bottom-right corner
116         srcRect.x += RepeatWidth();
117         srcRect.w = BorderWidth();
118         SDL_BlitSurface(surface, &srcRect, dest, &destRect);
119 }
120
121
122 void Frame::CreateTypeDescription() {
123         Frame f;
124
125         int imageId(TypeDescription::GetTypeId("Image"));
126         int vectorId(TypeDescription::GetTypeId("Vector"));
127
128         TypeDescription &td(TypeDescription::CreateOrGet("Frame"));
129         td.SetDescription(
130                         "A frame is basically a border + a background texture.\n"
131                         "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.");
132         td.SetConstructor(&Construct);
133         td.SetSize(sizeof(Frame));
134
135         td.AddField("image", FieldDescription(((char *)&f.surface) - ((char *)&f), imageId).SetReferenced().SetDescription("the underlying graphic from which the frame parts are cut"));
136         td.AddField("border", FieldDescription(((char *)&f.borderSize) - ((char *)&f), vectorId).SetDescription("size of the border part, dimensions of top-left corner"));
137         td.AddField("repeat", FieldDescription(((char *)&f.repeatSize) - ((char *)&f), vectorId).SetDescription("size of the repeat part, dimensions of a single tile of the background texture"));
138         td.AddField("offset", FieldDescription(((char *)&f.offset) - ((char *)&f), vectorId).SetDescription("offset into the image where to start cutting, coordinates of the top-left corner on the image"));
139 }
140
141 void Frame::Construct(void *data) {
142         new (data) Frame;
143 }
144
145 }