mirror of
https://github.com/4jcraft/4jcraft.git
synced 2026-04-24 13:23:37 +00:00
290 lines
8.5 KiB
C++
290 lines
8.5 KiB
C++
#include "StitchedTexture.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "Texture.h"
|
|
#include "TextureManager.h"
|
|
#include "util/StringHelpers.h"
|
|
#include "java/InputOutputStream/BufferedReader.h"
|
|
#include "minecraft/SharedConstants.h"
|
|
#include "minecraft/client/renderer/texture/custom/ClockTexture.h"
|
|
#include "minecraft/client/renderer/texture/custom/CompassTexture.h"
|
|
|
|
StitchedTexture* StitchedTexture::create(const std::string& name) {
|
|
// TODO: Generalize?
|
|
if (name.compare("clock") == 0) {
|
|
return new ClockTexture();
|
|
} else if (name.compare("compass") == 0) {
|
|
return new CompassTexture();
|
|
} else {
|
|
return new StitchedTexture(name, name);
|
|
}
|
|
}
|
|
|
|
StitchedTexture::StitchedTexture(const std::string& name,
|
|
const std::string& filename)
|
|
: name(name) {
|
|
// 4J Initialisers
|
|
source = nullptr;
|
|
rotated = false;
|
|
x = 0;
|
|
y = 0;
|
|
width = 0;
|
|
height = 0;
|
|
u0 = 0.0f;
|
|
u1 = 0.0f;
|
|
v0 = 0.0f;
|
|
v1 = 0.0f;
|
|
widthTranslation = 0.0f;
|
|
heightTranslation = 0.0f;
|
|
frame = 0;
|
|
subFrame = 0;
|
|
frameOverride = nullptr;
|
|
flags = 0;
|
|
frames = nullptr;
|
|
m_fileName = filename;
|
|
}
|
|
|
|
void StitchedTexture::freeFrameTextures() {
|
|
if (frames != nullptr) {
|
|
for (auto it = frames->begin(); it != frames->end(); ++it) {
|
|
TextureManager::getInstance()->unregisterTexture("", *it);
|
|
delete *it;
|
|
}
|
|
delete frames;
|
|
frames = nullptr;
|
|
}
|
|
}
|
|
|
|
StitchedTexture::~StitchedTexture() {
|
|
if (frames != nullptr) {
|
|
for (auto it = frames->begin(); it != frames->end(); ++it) {
|
|
delete *it;
|
|
}
|
|
delete frames;
|
|
frames = nullptr;
|
|
}
|
|
|
|
if (frameOverride != nullptr) {
|
|
delete frameOverride;
|
|
frameOverride = nullptr;
|
|
}
|
|
}
|
|
|
|
void StitchedTexture::initUVs(float U0, float V0, float U1, float V1) {
|
|
u0 = U0;
|
|
u1 = U1;
|
|
v0 = V0;
|
|
v1 = V1;
|
|
}
|
|
|
|
void StitchedTexture::init(Texture* source, std::vector<Texture*>* frames,
|
|
int x, int y, int width, int height, bool rotated) {
|
|
this->source = source;
|
|
this->frames = frames;
|
|
frame = -1; // Force an update of animated textures
|
|
this->x = x;
|
|
this->y = y;
|
|
this->width = width;
|
|
this->height = height;
|
|
this->rotated = rotated;
|
|
|
|
float marginX = 0.0f; // 0.01f / source->getWidth();
|
|
float marginY = 0.0f; // 0.01f / source->getHeight();
|
|
|
|
this->u0 = x / (float)source->getWidth() + marginX;
|
|
this->u1 = (x + width) / (float)source->getWidth() - marginX;
|
|
this->v0 = y / (float)source->getHeight() + marginY;
|
|
this->v1 = (y + height) / (float)source->getHeight() - marginY;
|
|
|
|
#ifndef _CONTENT_PACKAGE
|
|
bool addBreakpoint = false;
|
|
if (addBreakpoint) {
|
|
printf("\nTreeTop\n");
|
|
printf("u0 = %f\n", u0);
|
|
printf("u1 = %f\n", u1);
|
|
printf("v0 = %f\n", v0);
|
|
printf("v1 = %f\n", v1);
|
|
printf("\n\n");
|
|
}
|
|
#endif
|
|
|
|
this->widthTranslation = width / (float)SharedConstants::WORLD_RESOLUTION;
|
|
this->heightTranslation = height / (float)SharedConstants::WORLD_RESOLUTION;
|
|
}
|
|
|
|
void StitchedTexture::replaceWith(StitchedTexture* texture) {
|
|
init(texture->source, texture->frames, texture->x, texture->y,
|
|
texture->width, texture->height, texture->rotated);
|
|
}
|
|
|
|
int StitchedTexture::getX() const { return x; }
|
|
|
|
int StitchedTexture::getY() const { return y; }
|
|
|
|
int StitchedTexture::getWidth() const { return width; }
|
|
|
|
int StitchedTexture::getHeight() const { return height; }
|
|
|
|
static const float UVAdjust = (1.0f / 16.0f) / 256.0f;
|
|
|
|
float StitchedTexture::getU0(bool adjust /*=false*/) const {
|
|
return adjust ? (u0 + UVAdjust) : u0;
|
|
}
|
|
|
|
float StitchedTexture::getU1(bool adjust /*=false*/) const {
|
|
return adjust ? (u1 - UVAdjust) : u1;
|
|
}
|
|
|
|
float StitchedTexture::getU(double offset, bool adjust /*=false*/) const {
|
|
float diff = getU1(adjust) - getU0(adjust);
|
|
return getU0(adjust) +
|
|
(diff * ((float)offset / SharedConstants::WORLD_RESOLUTION));
|
|
}
|
|
|
|
float StitchedTexture::getV0(bool adjust /*=false*/) const {
|
|
return adjust ? (v0 + UVAdjust) : v0;
|
|
}
|
|
|
|
float StitchedTexture::getV1(bool adjust /*=false*/) const {
|
|
return adjust ? (v1 - UVAdjust) : v1;
|
|
}
|
|
|
|
float StitchedTexture::getV(double offset, bool adjust /*=false*/) const {
|
|
float diff = getV1(adjust) - getV0(adjust);
|
|
return getV0(adjust) +
|
|
(diff * ((float)offset / SharedConstants::WORLD_RESOLUTION));
|
|
}
|
|
|
|
std::string StitchedTexture::getName() const { return name; }
|
|
|
|
int StitchedTexture::getSourceWidth() const { return source->getWidth(); }
|
|
|
|
int StitchedTexture::getSourceHeight() const { return source->getHeight(); }
|
|
|
|
void StitchedTexture::cycleFrames() {
|
|
if (frameOverride != nullptr) {
|
|
std::pair<int, int> current = frameOverride->at(frame);
|
|
subFrame++;
|
|
if (subFrame >= current.second) {
|
|
int oldFrame = current.first;
|
|
frame = (frame + 1) % frameOverride->size();
|
|
subFrame = 0;
|
|
|
|
current = frameOverride->at(frame);
|
|
int newFrame = current.first;
|
|
if (oldFrame != newFrame && newFrame >= 0 &&
|
|
newFrame < frames->size()) {
|
|
source->blit(x, y, frames->at(newFrame), rotated);
|
|
}
|
|
}
|
|
|
|
} else {
|
|
int oldFrame = frame;
|
|
frame = (frame + 1) % frames->size();
|
|
|
|
if (oldFrame != frame) {
|
|
source->blit(x, y, frames->at(this->frame), rotated);
|
|
}
|
|
}
|
|
}
|
|
|
|
Texture* StitchedTexture::getSource() { return source; }
|
|
|
|
Texture* StitchedTexture::getFrame(int i) { return frames->at(0); }
|
|
|
|
int StitchedTexture::getFrames() { return frames ? frames->size() : 0; }
|
|
|
|
/**
|
|
* Loads animation frames from a file with the syntax, <code>
|
|
* 0,1,2,3,
|
|
* 4*10,5*10,
|
|
* 4*10,3,2,1,
|
|
* 0
|
|
* </code> or similar
|
|
*
|
|
* @param bufferedReader
|
|
*/
|
|
void StitchedTexture::loadAnimationFrames(BufferedReader* bufferedReader) {
|
|
if (frameOverride != nullptr) {
|
|
delete frameOverride;
|
|
frameOverride = nullptr;
|
|
}
|
|
frame = 0;
|
|
subFrame = 0;
|
|
|
|
intPairVector* results = new intPairVector();
|
|
|
|
// try {
|
|
std::string line = bufferedReader->readLine();
|
|
while (!line.empty()) {
|
|
line = trimString(line);
|
|
if (line.length() > 0) {
|
|
std::vector<std::string> tokens = stringSplit(line, ',');
|
|
// for (String token : tokens)
|
|
for (auto it = tokens.begin(); it != tokens.end(); ++it) {
|
|
std::string token = *it;
|
|
int multiPos = token.find_first_of('*');
|
|
if (multiPos > 0) {
|
|
int frame = fromWString<int>(token.substr(0, multiPos));
|
|
int count = fromWString<int>(token.substr(multiPos + 1));
|
|
results->push_back(intPairVector::value_type(frame, count));
|
|
} else {
|
|
int tokenVal = fromWString<int>(token);
|
|
results->push_back(intPairVector::value_type(tokenVal, 1));
|
|
}
|
|
}
|
|
}
|
|
line = bufferedReader->readLine();
|
|
}
|
|
//} catch (Exception e) {
|
|
// System.err.println("Failed to read animation info for " + name + ": " +
|
|
// e.getMessage());
|
|
//}
|
|
|
|
if (!results->empty() &&
|
|
results->size() < (SharedConstants::TICKS_PER_SECOND * 30)) {
|
|
frameOverride = results;
|
|
} else {
|
|
delete results;
|
|
}
|
|
}
|
|
|
|
void StitchedTexture::loadAnimationFrames(const std::string& string) {
|
|
if (frameOverride != nullptr) {
|
|
delete frameOverride;
|
|
frameOverride = nullptr;
|
|
}
|
|
frame = 0;
|
|
subFrame = 0;
|
|
|
|
intPairVector* results = new intPairVector();
|
|
|
|
std::vector<std::string> tokens = stringSplit(trimString(string), ',');
|
|
// for (String token : tokens)
|
|
for (auto it = tokens.begin(); it != tokens.end(); ++it) {
|
|
std::string token = trimString(*it);
|
|
int multiPos = token.find_first_of('*');
|
|
if (multiPos > 0) {
|
|
int frame = fromWString<int>(token.substr(0, multiPos));
|
|
int count = fromWString<int>(token.substr(multiPos + 1));
|
|
results->push_back(intPairVector::value_type(frame, count));
|
|
} else if (!token.empty()) {
|
|
int tokenVal = fromWString<int>(token);
|
|
results->push_back(intPairVector::value_type(tokenVal, 1));
|
|
}
|
|
}
|
|
|
|
if (!results->empty() &&
|
|
results->size() < (SharedConstants::TICKS_PER_SECOND * 30)) {
|
|
frameOverride = results;
|
|
} else {
|
|
delete results;
|
|
}
|
|
}
|
|
|
|
void StitchedTexture::setFlags(int flags) { this->flags = flags; }
|
|
|
|
int StitchedTexture::getFlags() const { return this->flags; }
|
|
|
|
bool StitchedTexture::hasOwnData() { return true; } |