void SpriteDefinition::init (const TextureDefinition& textureDefinition) { ExecutionTime e("Sprites loading"); LUA lua; if (!lua.load("sprites.lua")) { System.exit("could not load sprites", 1); return; } lua.getGlobalKeyValue("sprites"); while (lua.getNextKeyValue()) { const std::string id = lua.getKey(); if (id.empty()) { lua.pop(); continue; } SpriteDefMapConstIter findIter = _spriteDefs.find(id); if (findIter != _spriteDefs.end()) { error(LOG_GENERAL, "sprite def already defined: " + id); lua.pop(); continue; } const std::string typeStr = lua.getValueStringFromTable("type").str(); const SpriteType& type = SpriteType::getByName(typeStr); if (!type && !typeStr.empty()) { error(LOG_GENERAL, "invalid sprite type given: " + typeStr); } const ThemeType& theme = ThemeType::getByName(lua.getValueStringFromTable("theme").str()); SpriteDef *def = new SpriteDef(id, type, theme); def->fps = lua.getValueIntegerFromTable("fps", 20); def->redirect = lua.getValueStringFromTable("redirect").str(); def->width = lua.getValueFloatFromTable("width", 1.0f); def->height = lua.getValueFloatFromTable("height", 1.0f); def->angle = lua.getValueIntegerFromTable("angle", 0); def->rotateable = lua.getValueIntegerFromTable("rotateable", 0); def->friction = lua.getValueFloatFromTable("friction", 0.2f); def->restitution = lua.getValueFloatFromTable("restitution", 0.0f); // push the frames table const int layers = lua.getTable("frames"); for (Layer layer = LAYER_BACK; layer < layers; layer++) { lua_pushinteger(lua.getState(), layer + 1); lua_gettable(lua.getState(), -2); // push the frame table const int framesOnLayer = lua_rawlen(lua.getState(), -1); for (int i = 1; i <= framesOnLayer; ++i) { const std::string texture = lua.getTableString(i); const SpriteDefFrame frame(texture, 0, true); def->textures[layer].push_back(frame); } // pop the frame table lua.pop(); } // pop the frames table lua.pop(); // push the polygons table const int polygons = lua.getTable("polygons"); if (polygons > 0) { for (int j = 1; j <= polygons; j++) { lua_pushinteger(lua.getState(), j); lua_gettable(lua.getState(), -2); // push the polygon table const int vertices = lua_rawlen(lua.getState(), -1) - 1; const std::string userData = lua.getTableString(1); SpritePolygon p(userData); for (int i = 2; i <= vertices; i += 2) { const float x = lua.getTableInteger(i) / 100.0f; const float y = lua.getTableInteger(i + 1) / 100.0f; p.vertices.push_back(SpriteVertex(x, y)); } // pop the polygon table lua.pop(); def->polygons.push_back(p); } } // pop the polygons table lua.pop(); // push the circles table const int circles = lua.getTable("circles"); for (int j = 1; j <= circles; j++) { lua_pushinteger(lua.getState(), j); lua_gettable(lua.getState(), -2); // push the circle table const int entries = lua_rawlen(lua.getState(), -1); if (entries == 4) { const std::string userData = lua.getTableString(1); SpriteCircle p(userData); const float x = lua.getTableInteger(2) / 100.0f; const float y = lua.getTableInteger(3) / 100.0f; p.center = SpriteVertex(x, y); p.radius = lua.getTableInteger(4) / 100.0f; def->circles.push_back(p); } else { error(LOG_GENERAL, "invalid amount of entries for the circle shape"); } // pop the circle table lua.pop(); } // pop the circles table lua.pop(); for (Layer layer = LAYER_BACK; layer <= MAX_LAYERS; layer++) { if (layer == MAX_LAYERS || def->textures[layer].empty()) { int frame = 1; std::string spriteFrameName = def->id; switch (layer) { case LAYER_BACK: spriteFrameName += "-back-01"; break; case LAYER_FRONT: spriteFrameName += "-front-01"; break; case LAYER_MIDDLE: spriteFrameName += "-middle-01"; break; case MAX_LAYERS: // fallback spriteFrameName += "-01"; break; default: break; } const size_t length = spriteFrameName.size(); char frameNumbers[] = { '0', '1', '\0' }; Layer layerToUse = layer; if (layerToUse == MAX_LAYERS) layerToUse = LAYER_MIDDLE; for (;;) { if (!textureDefinition.exists(spriteFrameName)) break; def->textures[layerToUse].push_back(SpriteDefFrame(spriteFrameName, 0, true)); frame++; const char first = frame / 10 + '0'; const char second = frame % 10 + '0'; frameNumbers[0] = first; frameNumbers[1] = second; spriteFrameName.replace(length - 2, length, frameNumbers); } } } const int actives = lua.getTable("active"); for (int i = 1; i <= actives; ++i) { const bool active = lua.getTableBool(i); for (Layer layer = LAYER_BACK; layer < MAX_LAYERS; layer++) { const size_t textures = def->textures[layer].size(); if (textures < i) continue; SpriteDef::SpriteDefFrames& frames = def->textures[layer]; frames[i - 1].active = active; } } // pop the active table lua.pop(); const int delays = lua.getTable("delays"); for (int i = 1; i <= delays; ++i) { const int delay = lua.getTableInteger(i); for (Layer layer = LAYER_BACK; layer < MAX_LAYERS; layer++) { const size_t textures = def->textures[layer].size(); if (textures >= i) def->textures[layer][i - 1].delay = delay; } } // pop the delays table lua.pop(); lua.pop(); def->calcDelay(); _spriteDefs[id] = SpriteDefPtr(def); } }
void SpriteDefinition::init (const TextureDefinition& textureDefinition) { ExecutionTime e("Sprites loading"); Log::debug(LOG_COMMON, "Sprites loading"); LUA lua; if (!lua.load("sprites.lua")) { System.exit("could not load sprites", 1); return; } LUA_checkStack2(lua.getState()); if (!lua.getGlobalKeyValue("sprites")) { Log::error(LOG_COMMON, "spritedef: Could not find the global sprites map"); return; } while (lua.getNextKeyValue()) { LUA_checkStack2(lua.getState()); const std::string id = lua.getKey(); if (id.empty()) { Log::error(LOG_COMMON, "spritedef: no key found in definition: %s", lua.getStackDump().c_str()); lua.pop(); continue; } Log::debug(LOG_COMMON, "id: %s", id.c_str()); SpriteDefMapConstIter findIter = _spriteDefs.find(id); if (findIter != _spriteDefs.end()) { Log::error(LOG_COMMON, "sprite def already defined: %s", id.c_str()); lua.pop(); continue; } const std::string& typeStr = lua.getValueStringFromTable("type"); Log::debug(LOG_COMMON, "id: %s, type %s", id.c_str(), typeStr.c_str()); const SpriteType& type = SpriteType::getByName(typeStr); if (!type && !typeStr.empty()) { Log::error(LOG_COMMON, "invalid sprite type given: %s", typeStr.c_str()); } const ThemeType& theme = ThemeType::getByName(lua.getValueStringFromTable("theme")); SpriteDef *def = new SpriteDef(id, type, theme); def->fps = lua.getValueIntegerFromTable("fps", 20); def->redirect = lua.getValueStringFromTable("redirect"); def->width = lua.getValueFloatFromTable("width", 1.0f); def->height = lua.getValueFloatFromTable("height", 1.0f); def->angle = lua.getValueIntegerFromTable("angle", 0); def->rotateable = lua.getValueIntegerFromTable("rotateable", 0); def->friction = lua.getValueFloatFromTable("friction", 0.2f); def->restitution = lua.getValueFloatFromTable("restitution", 0.0f); // push the frames table const int layers = lua.getTable("frames"); Log::debug(LOG_COMMON, "id: %s => %i frames", id.c_str(), layers); if (layers > MAX_LAYERS) { Log::error(LOG_COMMON, "invalid sprite layer amount given for %s: %i", id.c_str(), layers); } if (layers > 0) { LUA_checkStack2(lua.getState()); lua_State* L = lua.getState(); lua_pushvalue(L, -1); lua_pushnil(L); Layer layer = LAYER_BACK; while (lua_next(L, -2)) { if (!lua_istable(lua.getState(), -1)) { Log::error(LOG_COMMON, "spritedef: expected frame table on the stack: %s", lua.getStackDump().c_str()); lua.pop(); continue; } // push the frame table const int framesOnLayer = lua_rawlen(lua.getState(), -1); Log::debug(LOG_COMMON, "id: %s => %i frames on layer %i", id.c_str(), framesOnLayer, layer); for (int i = 1; i <= framesOnLayer; ++i) { const std::string& texture = lua.getTableString(i); Log::debug(LOG_COMMON, "id: %s => texture %s on layer %i", id.c_str(), texture.c_str(), layer); const SpriteDefFrame frame(texture, 0, true); if (layer < MAX_LAYERS) def->textures[layer].push_back(frame); } lua.pop(); ++layer; } // pop the frame table lua.pop(); } // pop the frames table if (layers != -1) lua.pop(); // push the polygons table const int polygons = lua.getTable("polygons"); Log::debug(LOG_COMMON, "id: %s => %i polygons", id.c_str(), polygons); if (polygons > 0) { LUA_checkStack2(lua.getState()); lua_State* L = lua.getState(); lua_pushvalue(L, -1); lua_pushnil(L); while (lua_next(L, -2)) { if (!lua_istable(L, -1)) { Log::error(LOG_COMMON, "spritedef: expected polygon table on the stack: %s", lua.getStackDump().c_str()); lua.pop(); continue; } // push the polygon table const int vertices = lua_rawlen(L, -1) - 1; Log::debug(LOG_COMMON, "id: %s => %i vertices", id.c_str(), vertices); const std::string& userData = lua.getTableString(1); SpritePolygon p(userData); Log::debug(LOG_COMMON, "id: %s => %s userdata", id.c_str(), userData.c_str()); for (int i = 2; i <= vertices; i += 2) { const float x = lua.getTableFloat(i) / 100.0f; const float y = lua.getTableFloat(i + 1) / 100.0f; p.vertices.push_back(SpriteVertex(x, y)); } // pop the polygon table lua.pop(); def->polygons.push_back(p); } lua.pop(); } // pop the polygons table if (polygons != -1) lua.pop(); // push the circles table const int circles = lua.getTable("circles"); Log::debug(LOG_COMMON, "id: %s => %i circles", id.c_str(), circles); if (circles > 0) { LUA_checkStack2(lua.getState()); lua_State* L = lua.getState(); lua_pushvalue(L, -1); lua_pushnil(L); while (lua_next(L, -2)) { if (!lua_istable(L, -1)) { Log::error(LOG_COMMON, "spritedef: expected circle table on the stack: %s", lua.getStackDump().c_str()); lua.pop(); continue; } // push the circle table const int entries = lua_rawlen(lua.getState(), -1); if (entries == 4) { const std::string& userData = lua.getTableString(1); SpriteCircle p(userData); const float x = lua.getTableInteger(2) / 100.0f; const float y = lua.getTableInteger(3) / 100.0f; p.center = SpriteVertex(x, y); p.radius = lua.getTableInteger(4) / 100.0f; def->circles.push_back(p); } else { Log::error(LOG_COMMON, "invalid amount of entries for the circle shape"); } // pop the circle table lua.pop(); } lua.pop(); } // pop the circles table if (circles != -1) lua.pop(); for (Layer layer = LAYER_BACK; layer <= MAX_LAYERS; layer++) { if (layer == MAX_LAYERS || def->textures[layer].empty()) { int frame = 1; std::string spriteFrameName = def->id; switch (layer) { case LAYER_BACK: spriteFrameName += "-back-01"; break; case LAYER_FRONT: spriteFrameName += "-front-01"; break; case LAYER_MIDDLE: spriteFrameName += "-middle-01"; break; case MAX_LAYERS: // fallback spriteFrameName += "-01"; break; default: break; } const size_t length = spriteFrameName.size(); char frameNumbers[] = { '0', '1', '\0' }; Layer layerToUse = layer; if (layerToUse == MAX_LAYERS) layerToUse = LAYER_MIDDLE; for (;;) { if (!textureDefinition.exists(spriteFrameName)) break; def->textures[layerToUse].push_back(SpriteDefFrame(spriteFrameName, 0, true)); frame++; const char first = frame / 10 + '0'; const char second = frame % 10 + '0'; frameNumbers[0] = first; frameNumbers[1] = second; spriteFrameName.replace(length - 2, length, frameNumbers); } } } const int actives = lua.getTable("active"); for (int i = 1; i <= actives; ++i) { LUA_checkStack2(lua.getState()); const bool active = lua.getTableBool(i); for (Layer layer = LAYER_BACK; layer < MAX_LAYERS; layer++) { const int textures = def->textures[layer].size(); if (textures < i) continue; SpriteDef::SpriteDefFrames& frames = def->textures[layer]; frames[i - 1].active = active; } } // pop the active table if (actives != -1) lua.pop(); const int delays = lua.getTable("delays"); for (int i = 1; i <= delays; ++i) { LUA_checkStack2(lua.getState()); const int delay = lua.getTableInteger(i); for (Layer layer = LAYER_BACK; layer < MAX_LAYERS; layer++) { const int textures = def->textures[layer].size(); if (textures >= i) def->textures[layer][i - 1].delay = delay; } } // pop the delays table if (delays != -1) lua.pop(); lua.pop(); def->calcDelay(); _spriteDefs[id] = SpriteDefPtr(def); } }