Menu

[r487]: / trunk / Src / Graphics / New3D / TextureSheet.cpp  Maximize  Restore  History

Download this file

139 lines (103 with data), 3.2 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include "TextureSheet.h"
namespace New3D {
TextureSheet::TextureSheet()
{
m_temp.resize(512 * 512 * 4); // temporay buffer for textures
}
int TextureSheet::ToIndex(int x, int y)
{
return (y * 2048) + x;
}
std::shared_ptr<Texture> TextureSheet::BindTexture(const UINT16* src, int format, bool mirrorU, bool mirrorV, int x, int y, int width, int height)
{
//========
int index;
//========
x &= 2047;
y &= 2047;
if ((x + width) > 2048 || (y + height) > 2048) {
return 0;
}
if (width > 512 || height > 512) {
return 0;
}
index = ToIndex(x, y);
auto range = m_texMap[format].equal_range(index);
if (range.first == range.second) {
// nothing found so create a new texture
std::shared_ptr<Texture> t(new Texture());
m_texMap[format].insert(std::pair<int, std::shared_ptr<Texture>>(index, t));
t->UploadTexture(src, m_temp.data(), format, mirrorU, mirrorV, x, y, width, height);
return t;
}
else {
// iterate to try and find a match
for (auto it = range.first; it != range.second; ++it) {
int x2, y2, width2, height2, format2;
it->second->GetDetails(x2, y2, width2, height2, format2);
if (width == width2 && height == height2) {
return it->second;
}
}
// nothing found so create a new entry
std::shared_ptr<Texture> t(new Texture());
m_texMap[format].insert(std::pair<int, std::shared_ptr<Texture>>(index, t));
t->UploadTexture(src, m_temp.data(), format, mirrorU, mirrorV, x, y, width, height);
return t;
}
}
void TextureSheet::Release()
{
for (int i = 0; i < 12; i++) {
m_texMap[i].clear();
}
}
void TextureSheet::Invalidate(int x, int y, int width, int height)
{
//==========
int count;
int sWidth; // sample width
int sHeight; // sample height
//==========
// since the smallest sized texture is 32x32 pixels?
// we can invalidate 32x32 tiles over the width/height of the area
sWidth = width / 32;
sHeight = height / 32;
count = sWidth * sHeight;
for (int i = 0; i < count; i++) {
int index = ToIndex(x + ((i%sWidth) * 32), y + ((i / sWidth) * 32));
for (int j = 0; j<12; j++) {
if (m_texMap[j].count(index) > 0) {
m_texMap[j].erase(index);
}
}
}
}
int TextureSheet::GetTexFormat(int originalFormat, bool contour)
{
if (!contour) {
return originalFormat; // the same
}
switch (originalFormat)
{
case 1:
case 2:
case 3:
case 4:
return originalFormat + 7; // these formats are identical to 1-4, except they lose the 4 bit alpha part when contour is enabled
default:
return originalFormat;
}
}
void TextureSheet::GetMicrotexPos(int basePage, int id, int& x, int& y)
{
int xCoords[8] = { 0, 128, 0, 128, 0, 128, 0, 128 };
int yCoords[8] = { 0, 0, 128, 128, 0, 0, 128, 128 };
// i'm assuming .. the micro texture map is always on the other memory bank to the base texture
// this logic works for all our current games
// the microtextures are always on the top left of each texture sheet
basePage = (basePage + 1) & 1; // wrap around base page
x = xCoords[id];
y = xCoords[id] + (basePage * 1024);
}
} // New3D