diff --git a/spine-cpp/includes/spine/AtlasData.h b/spine-cpp/includes/spine/AtlasData.h new file mode 100644 index 000000000..c2a51fd08 --- /dev/null +++ b/spine-cpp/includes/spine/AtlasData.h @@ -0,0 +1,62 @@ +#ifndef SPINE_ATLASDATA_H_ +#define SPINE_ATLASDATA_H_ + +#include +#include +#include + +namespace spine { + +class AtlasPage; +class AtlasRegion; + +class AtlasData { +public: + std::vector pages; + std::vector regions; + + AtlasData (const char *begin, const char *end); + AtlasData (const std::string &json); + AtlasData (std::istream &file); + ~AtlasData (); + +private: + void init (const char *begin, const char *end); +}; + +enum Format { + alpha, intensity, luminanceAlpha, rgb565, rgba4444, rgb888, rgba8888 +}; + +enum TextureFilter { + nearest, linear, mipMap, mipMapNearestNearest, mipMapLinearNearest, mipMapNearestLinear, mipMapLinearLinear +}; + +enum TextureWrap { + mirroredRepeat, clampToEdge, repeat +}; + +class AtlasPage { +public: + std::string name; + Format format; + TextureFilter minFilter, magFilter; + TextureWrap uWrap, vWrap; +}; + +class AtlasRegion { +public: + std::string name; + AtlasPage *page; + int x, y, width, height; + float offsetX, offsetY; + int originalWidth, originalHeight; + int index; + bool rotate; + bool flip; + int *splits; + int *pads; +}; + +} /* namespace spine */ +#endif /* SPINE_ATLASDATA_H_ */ diff --git a/spine-cpp/src/main.cpp b/spine-cpp/src/main.cpp index 533f1b0fb..78f497d89 100644 --- a/spine-cpp/src/main.cpp +++ b/spine-cpp/src/main.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -25,6 +26,9 @@ int main () { } cout << flush; + ifstream file2("../uiskin.atlas"); + new AtlasData(file2); + sf::RenderWindow window(sf::VideoMode(640, 480), "Spine SFML"); window.setFramerateLimit(60); @@ -32,7 +36,7 @@ int main () { shape.setFillColor(sf::Color::Green); sf::Event event; - while (window.isOpen()) { + while (window.isOpen() && false) { while (window.pollEvent(event)) if (event.type == sf::Event::Closed) window.close(); window.clear(); diff --git a/spine-cpp/src/spine/AtlasData.cpp b/spine-cpp/src/spine/AtlasData.cpp new file mode 100644 index 000000000..5b4e661e8 --- /dev/null +++ b/spine-cpp/src/spine/AtlasData.cpp @@ -0,0 +1,169 @@ +#include +#include +#include +#include +#include +#include + +using std::string; +using std::runtime_error; + +namespace spine { + +static inline string& trim (string &s) { + s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun(std::isspace)))); + s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun(std::isspace))).base(), s.end()); + return s; +} + +static inline void readLine (const char *¤t, const char *end, string &value) { + const char *begin = current; + while (current != end) { + char c = *current++; + if (c == '\n') break; + } + value.clear(); + value.append(begin, current - 1); +} + +static inline string& readValue (const char *&begin, const char *end, string &value) { + readLine(begin, end, value); + int colon = value.find(':'); + if (colon == -1) throw runtime_error("Invalid line: " + value); + value = value.substr(colon + 1); + return trim(value); +} + +/** Returns the number of tuple values read (2 or 4). */ +static inline int readTuple (const char *&begin, const char *end, string &value, string tuple[4]) { + readLine(begin, end, value); + int colon = value.find(':'); + if (colon == -1) throw runtime_error("Invalid line: " + value); + int i = 0, lastMatch = colon + 1; + for (i = 0; i < 3; i++) { + int comma = value.find(',', lastMatch); + if (comma == -1) { + if (i == 0) throw runtime_error("Invalid line: " + value); + break; + } + tuple[i] = value.substr(lastMatch, comma - lastMatch); + trim(tuple[i]); + lastMatch = comma + 1; + } + tuple[i] = value.substr(lastMatch); + trim(tuple[i]); + return i + 1; +} + +static inline int indexOf (const string *array, int count, const string &value) { + for (int i = count - 1; i >= 0; i--) + if (array[i] == value) return i; + throw runtime_error("Invalid value: " + value); +} + +static string formatNames[] = {"Alpha", "Intensity", "LuminanceAlpha", "RGB565", "RGBA4444", "RGB888", "RGBA8888"}; +static string textureFilterNames[] = {"Nearest", "Linear", "MipMap", "MipMapNearestNearest", "MipMapLinearNearest", + "MipMapNearestLinear", "MipMapLinearLinear"}; + +AtlasData::AtlasData (std::istream &file) { + string text; + std::getline(file, text, (char)EOF); + const char *begin = text.c_str(); + const char *end = begin + text.length(); + init(begin, end); +} + +AtlasData::AtlasData (const string &text) { + const char *begin = text.c_str(); + const char *end = begin + text.length(); + init(begin, end); +} + +AtlasData::AtlasData (const char *begin, const char *end) { + init(begin, end); +} + +void AtlasData::init (const char *current, const char *end) { + string value; + string tuple[4]; + AtlasPage *page; + while (current != end) { + readLine(current, end, value); + trim(value); + if (value.length() == 0) { + page = 0; + } else if (!page) { + page = new AtlasPage(); + pages.push_back(page); + page->name = value; + page->format = static_cast(indexOf(formatNames, 7, readValue(current, end, value))); + + readTuple(current, end, value, tuple); + page->minFilter = static_cast(indexOf(textureFilterNames, 7, tuple[0])); + page->magFilter = static_cast(indexOf(textureFilterNames, 7, tuple[1])); + + readValue(current, end, value); + if (value == "x") { + page->uWrap = repeat; + page->vWrap = clampToEdge; + } else if (value == "y") { + page->uWrap = clampToEdge; + page->vWrap = repeat; + } else if (value == "xy") { + page->uWrap = repeat; + page->vWrap = repeat; + } + } else { + AtlasRegion *region = new AtlasRegion(); + regions.push_back(region); + region->name = value; + region->page = page; + + region->rotate = readValue(current, end, value) == "true"; + + readTuple(current, end, value, tuple); + region->x = atoi(tuple[0].c_str()); + region->y = atoi(tuple[1].c_str()); + + readTuple(current, end, value, tuple); + region->width = atoi(tuple[0].c_str()); + region->height = atoi(tuple[1].c_str()); + + if (readTuple(current, end, value, tuple) == 4) { // split is optional + region->splits = new int[4]; + region->splits[0] = atoi(tuple[0].c_str()); + region->splits[1] = atoi(tuple[1].c_str()); + region->splits[2] = atoi(tuple[2].c_str()); + region->splits[3] = atoi(tuple[3].c_str()); + + if (readTuple(current, end, value, tuple) == 4) { // pad is optional, but only present with splits + region->pads = new int[4]; + region->pads[0] = atoi(tuple[0].c_str()); + region->pads[1] = atoi(tuple[1].c_str()); + region->pads[2] = atoi(tuple[2].c_str()); + region->pads[3] = atoi(tuple[3].c_str()); + + readTuple(current, end, value, tuple); + } + } + + region->originalWidth = atoi(tuple[0].c_str()); + region->originalHeight = atoi(tuple[1].c_str()); + + readTuple(current, end, value, tuple); + region->offsetX = atoi(tuple[0].c_str()); + region->offsetY = atoi(tuple[1].c_str()); + + region->index = atoi(readValue(current, end, value).c_str()); + } + } +} + +AtlasData::~AtlasData () { + for (int i = 0, n = pages.size(); i < n; i++) + delete pages[i]; + for (int i = 0, n = regions.size(); i < n; i++) + delete regions[i]; +} + +} /* namespace spine */ diff --git a/spine-cpp/uiskin.atlas b/spine-cpp/uiskin.atlas new file mode 100644 index 000000000..c19358167 --- /dev/null +++ b/spine-cpp/uiskin.atlas @@ -0,0 +1,198 @@ + +uiskin.png +format: RGBA8888 +filter: Nearest,Nearest +repeat: none +default + rotate: false + xy: 1, 50 + size: 254, 77 + orig: 254, 77 + offset: 0, 0 + index: -1 +default-window + rotate: false + xy: 1, 20 + size: 27, 29 + split: 4, 3, 20, 3 + orig: 27, 29 + offset: 0, 0 + index: -1 +default-select + rotate: false + xy: 29, 29 + size: 27, 20 + split: 4, 14, 4, 4 + orig: 27, 20 + offset: 0, 0 + index: -1 +default-round-large + rotate: false + xy: 57, 29 + size: 20, 20 + split: 5, 5, 5, 4 + orig: 20, 20 + offset: 0, 0 + index: -1 +default-scroll + rotate: false + xy: 78, 29 + size: 20, 20 + split: 2, 2, 2, 2 + orig: 20, 20 + offset: 0, 0 + index: -1 +default-slider-knob + rotate: false + xy: 1, 1 + size: 9, 18 + orig: 9, 18 + offset: 0, 0 + index: -1 +default-round-down + rotate: false + xy: 99, 29 + size: 12, 20 + split: 5, 5, 5, 4 + orig: 12, 20 + offset: 0, 0 + index: -1 +default-round + rotate: false + xy: 112, 29 + size: 12, 20 + split: 5, 5, 5, 4 + pad: 4, 4, 1, 1 + orig: 12, 20 + offset: 0, 0 + index: -1 +check-off + rotate: false + xy: 11, 5 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +textfield + rotate: false + xy: 11, 5 + size: 14, 14 + split: 3, 3, 3, 3 + orig: 14, 14 + offset: 0, 0 + index: -1 +check-on + rotate: false + xy: 125, 35 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +tree-minus + rotate: false + xy: 140, 35 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +tree-plus + rotate: false + xy: 155, 35 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +default-slider + rotate: false + xy: 29, 20 + size: 8, 8 + split: 2, 2, 2, 2 + orig: 8, 8 + offset: 0, 0 + index: -1 +default-pane + rotate: false + xy: 11, 1 + size: 5, 3 + split: 1, 1, 1, 1 + orig: 5, 3 + offset: 0, 0 + index: -1 +default-rect-pad + rotate: false + xy: 11, 1 + size: 5, 3 + split: 1, 1, 1, 1 + orig: 5, 3 + offset: 0, 0 + index: -1 +default-splitpane + rotate: false + xy: 17, 1 + size: 5, 3 + split: 0, 5, 0, 0 + orig: 5, 3 + offset: 0, 0 + index: -1 +cursor + rotate: false + xy: 23, 1 + size: 3, 3 + split: 1, 1, 1, 1 + orig: 3, 3 + offset: 0, 0 + index: -1 +default-splitpane-vertical + rotate: false + xy: 125, 29 + size: 3, 5 + split: 0, 0, 0, 5 + orig: 3, 5 + offset: 0, 0 + index: -1 +default-rect-down + rotate: false + xy: 170, 46 + size: 3, 3 + split: 1, 1, 1, 1 + orig: 3, 3 + offset: 0, 0 + index: -1 +default-rect + rotate: false + xy: 38, 25 + size: 3, 3 + split: 1, 1, 1, 1 + orig: 3, 3 + offset: 0, 0 + index: -1 +default-select-selection + rotate: false + xy: 26, 16 + size: 3, 3 + split: 1, 1, 1, 1 + orig: 3, 3 + offset: 0, 0 + index: -1 +default-pane-noborder + rotate: false + xy: 129, 33 + size: 1, 1 + split: 0, 0, 0, 0 + orig: 1, 1 + offset: 0, 0 + index: -1 +selection + rotate: false + xy: 170, 44 + size: 1, 1 + orig: 1, 1 + offset: 0, 0 + index: -1 +white + rotate: false + xy: 174, 48 + size: 1, 1 + orig: 1, 1 + offset: 0, 0 + index: -1