~openhommdev/openhomm/gui

« back to all changes in this revision

Viewing changes to src/render/hrCache.cpp

  • Committer: Roman Fomin
  • Date: 2010-02-12 13:12:55 UTC
  • Revision ID: rfomin@gmail.com-20100212131255-glg00rmtls7wwc17
underground
some little fixes

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
// openhomm - open source clone of Heroes of Might and Magic III
2
 
// Copyright (C) 2009 openhomm developers team (see AUTHORS)
 
2
// Copyright (C) 2009-2010 openhomm developers team (see AUTHORS)
3
3
//
4
4
// This program is free software: you can redistribute it and/or modify
5
5
// it under the terms of the GNU General Public License as published by
17
17
#include "precompiled.hpp"
18
18
#include "hrCache.hpp"
19
19
 
20
 
const int HR_FILE_SIZE = 0;//200000;
 
20
const int HR_FILE_SIZE = 50000;
21
21
 
22
22
hrCache::hrCache() : inc(0), target(0)
23
23
{
24
 
    cache.setMaxCost(200);
 
24
    cache.setMaxCost(300);
25
25
 
26
26
    QDir dir;
27
27
    dir.mkdir("cache/");
28
 
    file.setFileName("cache/cache0");
29
 
    file.open(QIODevice::ReadOnly | QIODevice::Append);
 
28
    cacheFile.setFileName("cache/cache0");
 
29
    cacheFile.open(QIODevice::ReadOnly | QIODevice::Truncate | QIODevice::Append);
30
30
 
31
 
    QFile fileFat("cache/cache1");
 
31
    /*QFile fileFat("cache/cache1");
32
32
    if (fileFat.open(QIODevice::ReadOnly))
33
33
    {
34
34
        QDataStream in(&fileFat);
35
35
        in >> fat;
36
 
    }
 
36
    }*/
37
37
}
38
38
 
39
39
hrCache::~hrCache()
40
40
{
41
 
    QFile fileFat("cache/cache1");
 
41
    /*QFile fileFat("cache/cache1");
42
42
    if (fileFat.open(QIODevice::WriteOnly | QIODevice::Truncate))
43
43
    {
44
44
        QDataStream out(&fileFat);
45
45
        out << fat;
46
 
    }
 
46
    }*/
47
47
}
48
48
 
49
49
void hrCache::setTarget(GLuint textureTarget)
55
55
{
56
56
    hrCacheKey key = inc++;
57
57
 
58
 
    hrCacheItem *item = new hrCacheItem();
 
58
    hrCacheItem *item;
59
59
    if (fat.contains(name))
60
60
    {
61
 
        qint64 pos = fat[name];
62
 
        offsets[key] = pos;
63
 
 
64
 
        loadFromDiscPrepared(pos, item);
 
61
        item = LoadPrepared(fat[name]);
65
62
    }
66
63
    else
67
64
    {
68
 
        int size = loadFromDisc(name, item);
69
 
 
70
 
        if (size > HR_FILE_SIZE)
71
 
        {
72
 
            if (!file.atEnd())
73
 
            {
74
 
                file.seek(file.size());
75
 
            }
76
 
            fat[name] = file.pos();
77
 
            offsets[key] = file.pos();
78
 
 
79
 
            saveToDisc(name);
80
 
        }
81
 
        else
82
 
        {
83
 
            files[key] = name;
84
 
        }
 
65
        item = LoadAndPrepare(name);
85
66
    }
86
67
 
 
68
    files[key] = name;
 
69
 
87
70
    if (notDeletable)
88
71
    {
89
72
        map[key] = item;
96
79
    return hrGraphicsItem(key, item->countFrames(), item->getSize());
97
80
}
98
81
 
99
 
int hrCache::loadFromDisc(QString name, hrCacheItem* item)
 
82
 
 
83
hrCacheItem* hrCache::Load(const QString &name) const
100
84
{
101
 
    Q_ASSERT(item);
 
85
    hrCacheItem *item = new hrCacheItem();
102
86
 
103
87
    QImageReader ir("vfs:/" + name);
104
88
    QImage im;
105
 
    int bytes = 0;
106
 
    for (int i = 0; ir.jumpToImage(i); i++)
107
 
        if (ir.read(&im))
108
 
        {
109
 
            QImage conv = QGLWidget::convertToGLFormat(target == GL_TEXTURE_2D
110
 
                                                    ? ImageToPOT(im)
111
 
                                                    : im
112
 
                                                    );
113
 
            GLuint tx = bindImage(conv.bits(), conv.width(), conv.height());
114
 
            item->addFrame(tx);
115
 
            bytes += conv.byteCount();
116
 
        }
117
 
 
118
 
    if (ir.error())
119
 
    {
120
 
        qFatal("hrCache: %s", qPrintable(ir.errorString() + name));
121
 
    }
122
 
    item->setSize(im.size());
123
 
    return bytes;
124
 
}
125
 
 
126
 
void hrCache::loadFromDiscPrepared(qint64 pos, hrCacheItem *item)
127
 
{
128
 
    Q_ASSERT(item);
129
 
 
130
 
    file.seek(pos);
131
 
    QDataStream in(&file);
 
89
    for (int i = 0; ir.jumpToImage(i); i++)
 
90
        if (ir.read(&im))
 
91
        {
 
92
            QImage conv = QGLWidget::convertToGLFormat(target == GL_TEXTURE_2D
 
93
                                                    ? ImageToPOT(im)
 
94
                                                    : im
 
95
                                                    );
 
96
            GLuint tx = bindImage(conv.bits(), conv.width(), conv.height());
 
97
            item->addFrame(tx);
 
98
        }
 
99
    item->setSize(im.size());
 
100
 
 
101
    if (ir.error())
 
102
    {
 
103
        qFatal("hrCache: %s", qPrintable(ir.errorString() + name));
 
104
    }
 
105
 
 
106
    return item;
 
107
}
 
108
 
 
109
hrCacheItem* hrCache::LoadAndPrepare(const QString &name)
 
110
{
 
111
    hrCacheItem *item = new hrCacheItem();
 
112
 
 
113
    QFile file("vfs:/" + name);
 
114
    file.open(QIODevice::ReadOnly);
 
115
 
 
116
    bool isHeaderWrite = true;
 
117
    bool isFileLarge = false;
 
118
    if (file.size() > HR_FILE_SIZE)
 
119
    {
 
120
        isFileLarge = true;
 
121
 
 
122
        if (!cacheFile.atEnd())
 
123
        {
 
124
            cacheFile.seek(cacheFile.size());
 
125
        }
 
126
        fat[name] = cacheFile.pos();
 
127
    }
 
128
    QDataStream out(&cacheFile);
 
129
 
 
130
    QImageReader ir(&file);
 
131
    QImage im;
 
132
    for (int i = 0; ir.jumpToImage(i); i++)
 
133
    {
 
134
        if (ir.read(&im))
 
135
        {
 
136
            QImage conv = QGLWidget::convertToGLFormat(target == GL_TEXTURE_2D
 
137
                                                    ? ImageToPOT(im)
 
138
                                                    : im
 
139
                                                    );
 
140
            GLuint tx = bindImage(conv.bits(), conv.width(), conv.height());
 
141
            item->addFrame(tx);
 
142
            
 
143
            if (isFileLarge)
 
144
            {
 
145
                if (isHeaderWrite)
 
146
                {
 
147
                    out << im.size();
 
148
                    out << ir.imageCount();
 
149
                    isHeaderWrite = false;
 
150
                }
 
151
 
 
152
                out << QByteArray::fromRawData((char*)conv.bits(), conv.byteCount());
 
153
            }
 
154
        }
 
155
    }
 
156
    item->setSize(im.size());
 
157
 
 
158
    if (ir.error())
 
159
    {
 
160
        qFatal("hrCache: %s", qPrintable(ir.errorString() + name));
 
161
    }
 
162
    if (cacheFile.error())
 
163
    {
 
164
        qFatal("hrCache: %s", qPrintable(cacheFile.errorString()));
 
165
    }
 
166
    
 
167
    return item;
 
168
}
 
169
 
 
170
hrCacheItem* hrCache::LoadPrepared(qint64 pos)
 
171
{
 
172
    hrCacheItem *item = new hrCacheItem();
 
173
 
 
174
    cacheFile.seek(pos);
 
175
 
 
176
    QDataStream in(&cacheFile);
 
177
 
132
178
    QSize size;
133
179
    in >> size;
134
180
    item->setSize(size);
135
 
    QVector<QByteArray> images;
136
 
    in >> images;
137
 
    for (int i = 0; i < images.size(); i++)
 
181
    int count;
 
182
    in >> count;
 
183
    QByteArray image;
 
184
    for (int i = 0; i < count; i++)
138
185
    {
139
 
        GLuint tx = bindImage(images.at(i).data()
140
 
                              , size.width()
141
 
                              , size.height()
142
 
                              );
 
186
        in >> image;
 
187
        GLuint tx = bindImage(image.data(), size.width(), size.height());
143
188
        item->addFrame(tx);
144
189
    }
145
 
    if (file.error())
 
190
 
 
191
    if (cacheFile.error())
146
192
    {
147
 
        qFatal("hrCache: %s", qPrintable(file.errorString()));
 
193
        qFatal("hrCache: %s", qPrintable(cacheFile.errorString()));
148
194
    }
 
195
    return item;
149
196
}
150
197
 
151
198
GLuint hrCache::getTexture(const hrGraphicsItem &item)
159
206
    {
160
207
        cacheItem = cache[item.key];
161
208
    }
162
 
    else if (offsets.contains(item.key))
163
 
    {
164
 
        cacheItem = new hrCacheItem();
165
 
        loadFromDiscPrepared(offsets[item.key], cacheItem);
166
 
        cache.insert(item.key, cacheItem);
167
 
    }
168
209
    else if (files.contains(item.key))
169
210
    {
170
 
        cacheItem = new hrCacheItem();
171
 
        loadFromDisc(files[item.key], cacheItem);
 
211
        const QString &name = files[item.key];
 
212
        if (fat.contains(name))
 
213
        {
 
214
            cacheItem = LoadPrepared(fat[name]);
 
215
        }
 
216
        else
 
217
        {
 
218
            cacheItem = Load(name);
 
219
        }
172
220
        cache.insert(item.key, cacheItem);
173
221
    }
174
222
    else
175
223
    {
176
224
       qFatal("hrCache: key not found");
177
225
    }
178
 
    
 
226
 
179
227
    GLuint tx = cacheItem->getFrame(item.curFrame);
180
228
    return tx;
181
229
}
182
230
 
183
 
GLuint hrCache::bindImage(const GLvoid* image, int width, int height)
 
231
GLuint hrCache::bindImage(const GLvoid* image, int width, int height) const
184
232
{
185
233
    Q_ASSERT(target);
186
234
    GLuint format = GL_RGBA;
215
263
    return tx;
216
264
}
217
265
 
218
 
void hrCache::saveToDisc(QString name)
219
 
{
220
 
    QImageReader ir("vfs:/" + name);
221
 
    QVector<QByteArray> images;
222
 
    QImage im;
223
 
    for (int i = 0; ir.jumpToImage(i); i++)
224
 
    {
225
 
        if (ir.read(&im))
226
 
        {
227
 
            QImage conv = QGLWidget::convertToGLFormat(target == GL_TEXTURE_2D
228
 
                                                       ? ImageToPOT(im)
229
 
                                                       : im
230
 
                                                       );
231
 
            QByteArray bytes((char*)conv.bits(), conv.byteCount());
232
 
            images.append(bytes);
233
 
        }
234
 
    }
235
 
    if (ir.error())
236
 
    {
237
 
        qFatal("hrCache: %s", qPrintable(ir.errorString() + name));
238
 
    }
239
 
 
240
 
    QSize size = im.size();
241
 
 
242
 
    QDataStream out(&file);
243
 
    out << size;
244
 
    out << images;
245
 
 
246
 
    if (file.error())
247
 
    {
248
 
        qFatal("hrCache: %s", qPrintable(file.errorString()));
249
 
    }
250
 
}
251
 
 
252
266
QImage hrCache::ImageToPOT(const QImage &im) const
253
267
{
254
268
    int s = NearestGLTextureSize(qMax(im.width(), im.height()));