diff options
-rw-r--r-- | Changelog | 13 | ||||
-rw-r--r-- | assets/playerk.png | bin | 315 -> 496 bytes | |||
-rw-r--r-- | include/Texture.h | 3 | ||||
-rw-r--r-- | include/common.h | 2 | ||||
-rw-r--r-- | include/entities.h | 15 | ||||
-rw-r--r-- | include/inventory.h | 3 | ||||
-rw-r--r-- | include/ui.h | 2 | ||||
-rw-r--r-- | include/world.h | 3 | ||||
-rw-r--r-- | main.cpp | 42 | ||||
-rw-r--r-- | src/Texture.cpp | 14 | ||||
-rw-r--r-- | src/common.cpp | 19 | ||||
-rw-r--r-- | src/entities.cpp | 2 | ||||
-rw-r--r-- | src/gameplay.cpp | 105 | ||||
-rw-r--r-- | src/inventory.cpp | 4 | ||||
-rw-r--r-- | src/ui.cpp | 16 | ||||
-rw-r--r-- | src/world.cpp | 64 | ||||
-rw-r--r-- | xcf/playerk.xcf | bin | 0 -> 2789 bytes | |||
-rw-r--r-- | xml/playerSpawnHill1_Building1.xml | 2 |
18 files changed, 239 insertions, 70 deletions
@@ -547,3 +547,16 @@ - removed layers - switched world linking from pointers to file names, rewrote all world-linking code - worlds are now loaded dynamically + +1/19/2015: +========== + + - memory management + - began reconsidering save/load stuff + +1/20/2015: +========== + + - can save npc dialog positions + - worked on player sprite redesign + - greatly simplified/documented gameplay.cpp diff --git a/assets/playerk.png b/assets/playerk.png Binary files differindex 3dfb4dd..3f55392 100644 --- a/assets/playerk.png +++ b/assets/playerk.png diff --git a/include/Texture.h b/include/Texture.h index 7160d37..50681bf 100644 --- a/include/Texture.h +++ b/include/Texture.h @@ -28,6 +28,9 @@ namespace Texture{ */ GLuint loadTexture(const char *fileName); + + void freeTextures(void); + void initColorIndex(); vec2 getIndex(Color c); } diff --git a/include/common.h b/include/common.h index 763ecc6..4115f10 100644 --- a/include/common.h +++ b/include/common.h @@ -215,6 +215,8 @@ unsigned int millis(void); int getdir(const char *dir, std::vector<std::string> &files); void strVectorSortAlpha(std::vector<std::string> *v); +const char *readFile(const char *path); + int strCreateFunc(const char *equ); extern void *NULLPTR; diff --git a/include/entities.h b/include/entities.h index 7925bb9..d894c21 100644 --- a/include/entities.h +++ b/include/entities.h @@ -65,15 +65,13 @@ public: bool gravity; bool behind; Particles(float x, float y, float w, float h, float vx, float vy, Color c, float d){ - loc.x = (x); - loc.y = (y); - width = (w); - height = (h); + loc.x = x; + loc.y = y; + width = w; + height = h; velx = vx; vely = vy; - color.red = (c.red); - color.green = (c.green); - color.blue = (c.blue); + color = c; duration = d; fountain = false; gravity = true; @@ -186,7 +184,7 @@ public: class NPC : public Entity{ public: std::vector<int (*)(NPC *)>aiFunc; - unsigned int dialogIndex; + int dialogIndex; NPC(); ~NPC(); @@ -200,7 +198,6 @@ class Structures : public Entity{ public: BUILD_SUB bsubtype; char *inside; - //char *outside; Structures(); ~Structures(); diff --git a/include/inventory.h b/include/inventory.h index b035f91..a08954a 100644 --- a/include/inventory.h +++ b/include/inventory.h @@ -106,8 +106,9 @@ public: } }; -void itemUse(void *p); void initInventorySprites(void); +void destroyInventory(void); + char *getItemTexturePath(ITEM_ID id); int getItemWidth(ITEM_ID); int getItemHeight(ITEM_ID); diff --git a/include/ui.h b/include/ui.h index b769bbf..c018008 100644 --- a/include/ui.h +++ b/include/ui.h @@ -41,6 +41,8 @@ namespace ui { void initFonts(void); + void destroyFonts(void); + /* * Sets the current font/font size. */ diff --git a/include/world.h b/include/world.h index a1cc870..3209284 100644 --- a/include/world.h +++ b/include/world.h @@ -272,6 +272,9 @@ public: */ int getTheWidth(void); + + void save(void); + void load(void); }; /* @@ -167,25 +167,6 @@ void logic(void); void render(void); void mainLoop(void); -std::string readFile(const char *filePath) { - std::string content; - std::ifstream fileStream(filePath, std::ios::in); - - if(!fileStream.is_open()) { - std::cerr << "Could not read file " << filePath << ". File does not exist." << std::endl; - return "cancer"; - } - - std::string line = ""; - while(!fileStream.eof()) { - std::getline(fileStream, line); - content.append(line + "\n"); - } - - fileStream.close(); - return content; -} - /* * This offset is used as the player offset in the world drawing so * everything can be moved according to the player @@ -254,7 +235,6 @@ int main(/*int argc, char *argv[]*/){ Mix_AllocateChannels(8); // Run Mix_Quit when main returns - atexit(Mix_CloseAudio); atexit(Mix_Quit); /* @@ -358,21 +338,21 @@ int main(/*int argc, char *argv[]*/){ std::cout << "Initializing shaders!" << std::endl; - fragShader = glCreateShader(GL_FRAGMENT_SHADER); - - std::string shaderFileContents = readFile("frig.frag"); - const GLchar *shaderSource = shaderFileContents.c_str(); + const GLchar *shaderSource = readFile("test.frag"); - GLint bufferln = GL_FALSE; - int logLength; + GLint bufferln = 0; + int logLength; + fragShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragShader, 1, &shaderSource, NULL); glCompileShader(fragShader); glGetShaderiv(fragShader, GL_COMPILE_STATUS, &bufferln); glGetShaderiv(fragShader, GL_INFO_LOG_LENGTH, &logLength); - std::vector<char>fragShaderError((logLength > 1) ? logLength : 1); + + std::vector<char> fragShaderError ((logLength > 1) ? logLength : 1); + glGetShaderInfoLog(fragShader, logLength, NULL, &fragShaderError[0]); std::cout << &fragShaderError[0] << std::endl; @@ -391,6 +371,7 @@ int main(/*int argc, char *argv[]*/){ glGetProgramInfoLog(shaderProgram, logLength, NULL, &programError[0]); std::cout << &programError[0] << std::endl; + delete[] shaderSource; //glEnable(GL_DEPTH_TEST); //THIS DOESN'T WORK ON LINUX glEnable(GL_MULTISAMPLE); @@ -435,7 +416,7 @@ int main(/*int argc, char *argv[]*/){ **** GAMELOOP **** **************************/ - gameRunning=true; + gameRunning = true; while(gameRunning){ mainLoop(); } @@ -449,9 +430,14 @@ int main(/*int argc, char *argv[]*/){ */ Mix_HaltMusic(); + Mix_CloseAudio(); fb.close(); + destroyInventory(); + ui::destroyFonts(); + Texture::freeTextures(); + SDL_GL_DeleteContext(mainGLContext); SDL_DestroyWindow(window); diff --git a/src/Texture.cpp b/src/Texture.cpp index f688327..4418a3b 100644 --- a/src/Texture.cpp +++ b/src/Texture.cpp @@ -70,6 +70,14 @@ namespace Texture{ return object; } + + void freeTextures(void){ + for(unsigned int i=0;i<LoadedTextureCounter;i++){ + glDeleteTextures(1,&LoadedTexture[i]->tex); + delete[] LoadedTexture[i]->name; + delete LoadedTexture[i]; + } + } void initColorIndex(){ colorIndex = loadTexture("assets/colorIndex.png"); @@ -90,7 +98,7 @@ namespace Texture{ pixels[y][x].red = buffer[i++]; pixels[y][x].green = buffer[i++]; pixels[y][x].blue = buffer[i++]; - std::cout << pixels[y][x].red << "," << pixels[y][x].green << "," << pixels[y][x].blue << std::endl; + //std::cout << pixels[y][x].red << "," << pixels[y][x].green << "," << pixels[y][x].blue << std::endl; //std::cout << std::endl; } } @@ -111,7 +119,7 @@ namespace Texture{ float shit = 999; for(uint y = 0; y < 8; y++){ for(uint x = 0; x < 4; x++){ - std::cout << y << "," << x << ":" << pixels[y][x].red << "," << pixels[y][x].green << "," << pixels[y][x].blue << std::endl; + //std::cout << y << "," << x << ":" << pixels[y][x].red << "," << pixels[y][x].green << "," << pixels[y][x].blue << std::endl; buff = sqrt(pow((pixels[y][x].red- c.red), 2)+ pow((pixels[y][x].green-c.green),2)+ pow((pixels[y][x].blue- c.blue), 2)); @@ -126,7 +134,7 @@ namespace Texture{ } } ind.push_back({c, (int)buf[1], (int)buf[0]}); - std::cout << float(buf[1]) << ", " << float(buf[0]) << std::endl; + //std::cout << float(buf[1]) << ", " << float(buf[0]) << std::endl; return {float(buf[1]),float(buf[0])}; } } diff --git a/src/common.cpp b/src/common.cpp index 2d35313..334671e 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -93,7 +93,24 @@ void strVectorSortAlpha(std::vector<std::string> *v){ }while(change); } - +const char *readFile(const char *path){ + std::ifstream in (path,std::ios::in); + unsigned int size; + GLchar *buf; + + if(!in.is_open()){ + std::cout<<"Error reading file "<<path<<"!"<<std::endl; + abort(); + } + + in.seekg(0,in.end); + buf = new GLchar[(size = in.tellg())]; + in.seekg(0,in.beg); + in.read(buf,size); + + in.close(); + return buf; +} /*int strCreateFunc(const char *equ){ static unsigned int size; diff --git a/src/entities.cpp b/src/entities.cpp index 7817891..621dbde 100644 --- a/src/entities.cpp +++ b/src/entities.cpp @@ -143,6 +143,8 @@ Structures::~Structures(){ delete tex; if(name) delete[] name; + if(inside) + delete[] inside; } Mob::Mob(int sub){ diff --git a/src/gameplay.cpp b/src/gameplay.cpp index 486c16e..b8e51dc 100644 --- a/src/gameplay.cpp +++ b/src/gameplay.cpp @@ -20,21 +20,38 @@ std::vector<XMLElement *> dopt; int commonAIFunc(NPC *speaker){ XMLDocument xml; XMLElement *exml,*oxml; + const char *name; unsigned int idx = 0; bool stop = false; + /* + * Load the current world's XML file into memory for reading. + */ + xml.LoadFile(currentXML); exml = xml.FirstChildElement("Dialog"); + /* + * Search for the correct dialog block. + */ + while(strcmp(exml->Attribute("name"),speaker->name)) exml = exml->NextSiblingElement(); exml = exml->FirstChildElement(); + /* + * Search for which text block should be used. + */ + do{ if(!strcmp(exml->Name(),"text")){ - if(exml->UnsignedAttribute("id") == speaker->dialogIndex){ + if(exml->UnsignedAttribute("id") == (unsigned)speaker->dialogIndex){ + + /* + * Handle any 'give' requests. + */ if((oxml = exml->FirstChildElement("give"))){ while(oxml){ @@ -43,64 +60,106 @@ int commonAIFunc(NPC *speaker){ } } + /* + * Handle any 'take' requests. + */ + + if((oxml = exml->FirstChildElement("take"))){ + while(oxml){ + player->inv->takeItem((ITEM_ID)oxml->UnsignedAttribute("id"),oxml->UnsignedAttribute("count")); + oxml = oxml->NextSiblingElement(); + } + } + + /* + * Handle dialog options. + */ + if((oxml = exml->FirstChildElement("option"))){ - const char *op; - char *bp1 = new char[1],*bp2,*tmp; - bp1[0] = '\0'; + + /* + * Convert the list of options into a single colon-separated string. + */ + + std::string optstr; + while(oxml){ - op = oxml->Attribute("text"); - - bp2 = new char[strlen(bp1) + strlen(op) + 2]; - strcpy(bp2,bp1); - bp2[idx++] = ':'; - strcpy(bp2+idx,op); - idx += strlen(op); + /* + * Create a buffer big enough for the next option. + */ + + optstr.append((std::string)":" + oxml->Attribute("text")); - tmp = bp1; - bp1 = bp2; - delete[] tmp; + /* + * Append the next option. + */ dopt.push_back(oxml); oxml = oxml->NextSiblingElement(); } - ui::dialogBox(speaker->name,bp1,false,exml->GetText()); + /* + * Get the player's choice, then set the XMLElement to the option's block. + */ + + ui::dialogBox(speaker->name,optstr.c_str(),false,exml->GetText()); ui::waitForDialog(); - if(ui::dialogOptChosen){ + + if(ui::dialogOptChosen) exml = dopt[ui::dialogOptChosen-1]; - } + while(!dopt.empty()) dopt.pop_back(); }else{ + + /* + * No options - simply print the text. + */ + ui::dialogBox(speaker->name,"",false,exml->GetText()); ui::waitForDialog(); } + + /* + * Give another NPC dialog if requested. + */ + if((name = exml->Attribute("call"))){ for(auto &n : currentWorld->npc){ if(!strcmp(n->name,name)){ - if(exml->QueryUnsignedAttribute("callid",&idx) == XML_NO_ERROR){ + if(exml->QueryUnsignedAttribute("callid",&idx) == XML_NO_ERROR) n->dialogIndex = idx; - } n->addAIFunc(commonAIFunc,false); break; } } } + + /* + * Handle the next dialog block if this one leads to another. + */ + if(exml->QueryUnsignedAttribute("nextid",&idx) == XML_NO_ERROR){ speaker->dialogIndex = idx; - if(exml->QueryBoolAttribute("stop",&stop) == XML_NO_ERROR && stop) + + if(exml->QueryBoolAttribute("stop",&stop) == XML_NO_ERROR && stop){ + speaker->dialogIndex = -1; return 0; - else if(exml->QueryBoolAttribute("pause",&stop) == XML_NO_ERROR && stop) + }else if(exml->QueryBoolAttribute("pause",&stop) == XML_NO_ERROR && stop){ + speaker->dialogIndex = -1; return 1; - else return commonAIFunc(speaker); + }else return commonAIFunc(speaker); } return 0; } } + exml = exml->NextSiblingElement(); + }while(exml); + return 0; } @@ -155,6 +214,8 @@ extern std::vector<int (*)(NPC *)> AIpreload; extern std::vector<NPC *> AIpreaddr; void destroyEverything(void){ + currentWorld->save(); + delete currentWorld; while(!AIpreload.empty()) AIpreload.pop_back(); diff --git a/src/inventory.cpp b/src/inventory.cpp index b6819d1..108051c 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -29,6 +29,10 @@ void initInventorySprites(void){ Mix_Volume(2,100); } +void destroyInventory(void){ + Mix_FreeChunk(swordSwing); +} + char *getItemTexturePath(ITEM_ID id){ return item[id].textureLoc; } @@ -67,6 +67,8 @@ unsigned int fadeIntensity = 0; bool inBattle = false; Mix_Chunk *battleStart; +Mix_Chunk *sanic; + namespace ui { /* @@ -119,9 +121,20 @@ namespace ui { DEBUG_printf("Initialized FreeType2.\n",NULL); #endif // DEBUG dialogClick = Mix_LoadWAV("assets/click.wav"); + battleStart = Mix_LoadWAV("assets/sounds/frig.wav"); + sanic = Mix_LoadWAV("assets/sounds/sanic.wav"); Mix_Volume(1,50); } + void destroyFonts(void){ + FT_Done_Face(ftf); + FT_Done_FreeType(ftl); + + Mix_FreeChunk(dialogClick); + Mix_FreeChunk(battleStart); + Mix_FreeChunk(sanic); + } + /* * Sets a new font family to use (*.ttf). */ @@ -740,8 +753,6 @@ DONE: break; case SDLK_LSHIFT: if(debug){ - Mix_Chunk *sanic; - sanic = Mix_LoadWAV("assets/sounds/sanic.wav"); Mix_PlayChannel(1,sanic,-1); player->speed = 4.0f; }else @@ -885,7 +896,6 @@ DONE: fadeEnable ^= true; fadeWhite = true; fadeFast = true; - battleStart = Mix_LoadWAV("assets/sounds/frig.wav"); Mix_PlayChannel(1,battleStart,0); } } diff --git a/src/world.cpp b/src/world.cpp index 3ad877b..ed1b522 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -102,7 +102,7 @@ void World::deleteEntities(void){ entity.pop_back(); } while(!particles.empty()){ - //delete particles.back(); + delete particles.back(); particles.pop_back(); } while(!light.empty()){ @@ -121,6 +121,9 @@ World::~World(void){ delete bgTex; delete[] star; delete[] line; + + delete[] toLeft; + delete[] toRight; deleteEntities(); } @@ -1150,6 +1153,51 @@ int World::getTheWidth(void){ return -hey->x_start*2; } +void World::save(void){ + static std::string data; + + std::string save = (std::string)currentXML + ".dat"; + std::ofstream out (save,std::ios::out | std::ios::binary); + + std::cout<<"Saving to "<<save<<" ..."<<std::endl; + + //data.append(std::to_string(npc.size()) + "\n"); + for(auto &n : npc) + data.append(std::to_string(n->dialogIndex) + "\n"); + + data.append("dOnE\0"); + out.write(data.c_str(),data.size()); + + out.close(); +} + +#include <sstream> + +extern int commonAIFunc(NPC *); + +void World::load(void){ + std::string save,data,line; + + save = (std::string)currentXML + ".dat"; + data = readFile(save.c_str()); + std::istringstream iss (data); + + for(auto &n : npc){ + std::getline(iss,line); + if((n->dialogIndex = std::stoi(line)) != -1) + n->addAIFunc(commonAIFunc,false); + } + + while(std::getline(iss,line)){ + if(line == "dOnE") + break; + + std::cout<<line<<std::endl; + } + + //abort(); +} + IndoorWorld::IndoorWorld(void){ } @@ -1306,7 +1354,7 @@ using namespace tinyxml2; char *currentXML = NULL; -extern int commonAIFunc(NPC *); +extern World *currentWorld; World *loadWorldFromXML(const char *path){ XMLDocument xml; @@ -1320,8 +1368,10 @@ World *loadWorldFromXML(const char *path){ unsigned int size = 5 + strlen(path); - if(currentXML) + if(currentXML){ + currentWorld->save(); delete[] currentXML; + } memset((currentXML = new char[size]),0,size); strcpy(currentXML,"xml/"); @@ -1388,6 +1438,7 @@ World *loadWorldFromXML(const char *path){ dialog = false; if(wxml->QueryBoolAttribute("hasDialog",&dialog) == XML_NO_ERROR && dialog) tmp->npc.back()->addAIFunc(commonAIFunc,false); + else tmp->npc.back()->dialogIndex = -1; }else if(!strcmp(name,"structure")){ ptr = wxml->Attribute("inside"); @@ -1398,5 +1449,12 @@ World *loadWorldFromXML(const char *path){ } wxml = wxml->NextSiblingElement(); } + + std::ifstream dat (((std::string)currentXML + ".dat").c_str()); + if(dat.good()){ + dat.close(); + tmp->load(); + } + return tmp; } diff --git a/xcf/playerk.xcf b/xcf/playerk.xcf Binary files differnew file mode 100644 index 0000000..697edae --- /dev/null +++ b/xcf/playerk.xcf diff --git a/xml/playerSpawnHill1_Building1.xml b/xml/playerSpawnHill1_Building1.xml index 1580bd2..f33fcf5 100644 --- a/xml/playerSpawnHill1_Building1.xml +++ b/xml/playerSpawnHill1_Building1.xml @@ -2,6 +2,8 @@ <IndoorWorld> <style background="1" bgm="assets/music/theme_jazz.wav" /> <generation type="Random" width="300" /> + + <npc name="Bob" /> </IndoorWorld> |