]> git.lizzy.rs Git - dragonfireclient.git/blob - src/irrlichtwrapper.cpp
changes to handing of digging (non backwards-compatible i guess)
[dragonfireclient.git] / src / irrlichtwrapper.cpp
1 #include "irrlichtwrapper.h"
2
3 IrrlichtWrapper::IrrlichtWrapper(IrrlichtDevice *device)
4 {
5         m_main_thread = get_current_thread_id();
6         m_device_mutex.Init();
7         m_device = device;
8 }
9
10 void IrrlichtWrapper::Run()
11 {
12         /*
13                 Fetch textures
14         */
15         if(m_get_texture_queue.size() > 0)
16         {
17                 GetRequest<TextureSpec, video::ITexture*, u8, u8>
18                                 request = m_get_texture_queue.pop();
19
20                 dstream<<"got texture request with key.name="
21                                 <<request.key.name<<std::endl;
22
23                 GetResult<TextureSpec, video::ITexture*, u8, u8>
24                                 result;
25                 result.key = request.key;
26                 result.callers = request.callers;
27                 result.item = getTextureDirect(request.key);
28
29                 request.dest->push_back(result);
30         }
31 }
32
33 video::ITexture* IrrlichtWrapper::getTexture(TextureSpec spec)
34 {
35         video::ITexture *t = m_texturecache.get(spec.name);
36         if(t != NULL)
37                 return t;
38         
39         if(get_current_thread_id() == m_main_thread)
40         {
41                 dstream<<"Getting texture directly: name="
42                                 <<spec.name<<std::endl;
43                                 
44                 t = getTextureDirect(spec);
45         }
46         else
47         {
48                 // We're gonna ask the result to be put into here
49                 ResultQueue<TextureSpec, video::ITexture*, u8, u8> result_queue;
50                 
51                 // Throw a request in
52                 m_get_texture_queue.add(spec, 0, 0, &result_queue);
53                 
54                 dstream<<"Waiting for texture from main thread: "
55                                 <<spec.name<<std::endl;
56                 
57                 try
58                 {
59                         // Wait result for a second
60                         GetResult<TextureSpec, video::ITexture*, u8, u8>
61                                         result = result_queue.pop_front(1000);
62                 
63                         // Check that at least something worked OK
64                         assert(result.key.name == spec.name);
65
66                         t = result.item;
67                 }
68                 catch(ItemNotFoundException &e)
69                 {
70                         dstream<<"Waiting for texture timed out."<<std::endl;
71                         t = NULL;
72                 }
73         }
74
75         // Add to cache and return
76         m_texturecache.set(spec.name, t);
77         return t;
78 }
79
80 video::ITexture* IrrlichtWrapper::getTexture(const std::string &path)
81 {
82         return getTexture(TextureSpec(path, path, NULL));
83 }
84
85 /*
86         Non-thread-safe functions
87 */
88
89 video::ITexture* IrrlichtWrapper::getTextureDirect(TextureSpec spec)
90 {
91         video::IVideoDriver* driver = m_device->getVideoDriver();
92         
93         if(spec.mod == NULL)
94         {
95                 dstream<<"IrrlichtWrapper::getTextureDirect: Loading texture "
96                                 <<spec.path<<std::endl;
97                 return driver->getTexture(spec.path.c_str());
98         }
99
100         dstream<<"IrrlichtWrapper::getTextureDirect: Loading and modifying "
101                         "texture "<<spec.path<<" to make "<<spec.name<<std::endl;
102
103         video::ITexture *base = driver->getTexture(spec.path.c_str());
104         video::ITexture *result = spec.mod->make(base, spec.name.c_str(), driver);
105
106         delete spec.mod;
107         
108         return result;
109 }
110
111 video::ITexture * CrackTextureMod::make(video::ITexture *original,
112                 const char *newname, video::IVideoDriver* driver)
113 {
114         core::dimension2d<u32> dim(16, 16);
115         core::position2d<s32> pos_base(0, 0);
116         core::position2d<s32> pos_other(0, 16 * progression);
117
118         video::IImage *baseimage = driver->createImage(original, pos_base, dim);
119         assert(baseimage);
120         
121         video::ITexture *other = driver->getTexture("../data/crack.png");
122         // We have to get the whole texture because getting a smaller area
123         // messes the whole thing. It is probably a bug in Irrlicht.
124         video::IImage *otherimage = driver->createImage(
125                         other, core::position2d<s32>(0,0), other->getSize());
126
127         assert(otherimage);
128         
129         /*core::rect<s32> clip_rect(v2s32(0,0), dim);
130         otherimage->copyToWithAlpha(baseimage, v2s32(0,0),
131                         core::rect<s32>(pos_other, dim),
132                         video::SColor(255,255,255,255),
133                         &clip_rect);*/
134         
135         otherimage->copyToWithAlpha(baseimage, v2s32(0,0),
136                         core::rect<s32>(pos_other, dim),
137                         video::SColor(255,255,255,255),
138                         NULL);
139         
140         otherimage->drop();
141
142         video::ITexture *newtexture = driver->addTexture(newname, baseimage);
143
144         baseimage->drop();
145
146         return newtexture;
147 }
148
149 #if 0
150 video::ITexture * createAlphaBlitTexture(const char *name, video::ITexture *base,
151                 video::ITexture *other, v2u32 size, v2s32 pos_base, v2s32 pos_other)
152 {
153         if(g_device == NULL)
154                 return NULL;
155         video::IVideoDriver* driver = g_device->getVideoDriver();
156
157         core::dimension2d<u32> dim(size.X, size.Y);
158
159         video::IImage *baseimage = driver->createImage(
160                         base,
161                         core::position2d<s32>(pos_base.X, pos_base.Y),
162                         dim);
163         assert(baseimage);
164
165         video::IImage *otherimage = driver->createImage(
166                         other,
167                         core::position2d<s32>(pos_other.X, pos_other.Y),
168                         dim);
169         assert(sourceimage);
170         
171         otherimage->copyToWithAlpha(baseimage, v2s32(0,0),
172                         core::rect<s32>(v2s32(0,0), dim),
173                         video::SColor(255,255,255,255),
174                         core::rect<s32>(v2s32(0,0), dim));
175         otherimage->drop();
176
177         video::ITexture *newtexture = driver->addTexture(name, baseimage);
178
179         baseimage->drop();
180
181         return newtexture;
182 }
183 #endif
184