diff --git a/SConscript b/SConscript index ccbf859c3..a77fa5a8f 100644 --- a/SConscript +++ b/SConscript @@ -112,7 +112,7 @@ if(GetOption('lin32') or GetOption('lin64')): if(GetOption('release')): - ev.Append(CCFLAGS='-O3') + env.Append(CCFLAGS='-O3') if(GetOption('opengl')): env.Append(CPPDEFINES=["OGLI", "PIX32OGL"]) diff --git a/src/client/GameSave.cpp b/src/client/GameSave.cpp index 7f8aa4fc3..c03536cf1 100644 --- a/src/client/GameSave.cpp +++ b/src/client/GameSave.cpp @@ -22,7 +22,13 @@ gravityMode(save.gravityMode), airMode(save.airMode), signs(save.signs) { - blockMap, blockMapPtr, fanVelX, fanVelXPtr, fanVelY, fanVelYPtr, particles = NULL; + blockMap = NULL; + blockMapPtr = NULL; + fanVelX = NULL; + fanVelXPtr = NULL; + fanVelY = NULL; + fanVelYPtr = NULL; + particles = NULL; setSize(save.blockWidth, save.blockHeight); @@ -35,14 +41,30 @@ signs(save.signs) GameSave::GameSave(int width, int height) { - blockMap, blockMapPtr, fanVelX, fanVelXPtr, fanVelY, fanVelYPtr, particles = NULL; + blockMap = NULL; + blockMapPtr = NULL; + fanVelX = NULL; + fanVelXPtr = NULL; + fanVelY = NULL; + fanVelYPtr = NULL; + particles = NULL; + setSize(width, height); } GameSave::GameSave(char * data, int dataSize) { - blockWidth, blockHeight = 0; - blockMap, blockMapPtr, fanVelX, fanVelXPtr, fanVelY, fanVelYPtr, particles = NULL; + blockWidth = 0; + blockHeight = 0; + + blockMap = NULL; + blockMapPtr = NULL; + fanVelX = NULL; + fanVelXPtr = NULL; + fanVelY = NULL; + fanVelYPtr = NULL; + particles = NULL; + try { if(dataSize > 0) { @@ -65,6 +87,7 @@ GameSave::GameSave(char * data, int dataSize) throw ParseException(ParseException::Corrupt, "No data"); } } catch (ParseException& e) { + std::cout << e.what() << std::endl; this->~GameSave(); //Free any allocated memory throw; } @@ -487,7 +510,41 @@ void GameSave::readOPS(char * data, int dataLength) { if (wallData[y*blockW+x]) blockMap[blockY+y][blockX+x] = wallData[y*blockW+x]; - if (wallData[y*blockW+x] == WL_FAN && fanData) + + if (blockMap[y][x]==O_WL_WALLELEC) + blockMap[y][x]=WL_WALLELEC; + if (blockMap[y][x]==O_WL_EWALL) + blockMap[y][x]=WL_EWALL; + if (blockMap[y][x]==O_WL_DETECT) + blockMap[y][x]=WL_DETECT; + if (blockMap[y][x]==O_WL_STREAM) + blockMap[y][x]=WL_STREAM; + if (blockMap[y][x]==O_WL_FAN||blockMap[y][x]==O_WL_FANHELPER) + blockMap[y][x]=WL_FAN; + if (blockMap[y][x]==O_WL_ALLOWLIQUID) + blockMap[y][x]=WL_ALLOWLIQUID; + if (blockMap[y][x]==O_WL_DESTROYALL) + blockMap[y][x]=WL_DESTROYALL; + if (blockMap[y][x]==O_WL_ERASE) + blockMap[y][x]=WL_ERASE; + if (blockMap[y][x]==O_WL_WALL) + blockMap[y][x]=WL_WALL; + if (blockMap[y][x]==O_WL_ALLOWAIR) + blockMap[y][x]=WL_ALLOWAIR; + if (blockMap[y][x]==O_WL_ALLOWSOLID) + blockMap[y][x]=WL_ALLOWSOLID; + if (blockMap[y][x]==O_WL_ALLOWALLELEC) + blockMap[y][x]=WL_ALLOWALLELEC; + if (blockMap[y][x]==O_WL_EHOLE) + blockMap[y][x]=WL_EHOLE; + if (blockMap[y][x]==O_WL_ALLOWGAS) + blockMap[y][x]=WL_ALLOWGAS; + if (blockMap[y][x]==O_WL_GRAV) + blockMap[y][x]=WL_GRAV; + if (blockMap[y][x]==O_WL_ALLOWENERGY) + blockMap[y][x]=WL_ALLOWENERGY; + + if (blockMap[y][x] == WL_FAN && fanData) { if(j+1 >= fanDataLen) { @@ -736,6 +793,9 @@ void GameSave::readPSv(char * data, int dataLength) free(golTypesT); vector elements = GetElements(); + + try + { //New file header uses PSv, replacing fuC. This is to detect if the client uses a new save format for temperatures //This creates a problem for old clients, that display and "corrupt" error instead of a "newer version" error @@ -802,6 +862,8 @@ void GameSave::readPSv(char * data, int dataLength) if (BZ2_bzBuffToBuffDecompress((char *)d, (unsigned *)&i, (char *)(c+12), dataLength-12, 0, 0)) throw ParseException(ParseException::Corrupt, "Cannot decompress"); dataLength = i; + + std::cout << "Parsing " << dataLength << " bytes of data, version " << ver << std::endl; if (dataLength < bw*bh) throw ParseException(ParseException::Corrupt, "Save data corrupt (missing data)"); @@ -897,18 +959,18 @@ void GameSave::readPSv(char * data, int dataLength) } for (y=by0; y= dataLength) - goto corrupt; + throw ParseException(ParseException::Corrupt, "Not enough data at line " MTOS(__LINE__) " in " MTOS(__FILE__)); fanVelX[y][x] = (d[p++]-127.0f)/64.0f; } for (y=by0; y= dataLength) - goto corrupt; + throw ParseException(ParseException::Corrupt, "Not enough data at line " MTOS(__LINE__) " in " MTOS(__FILE__)); fanVelY[y][x] = (d[p++]-127.0f)/64.0f; } @@ -920,11 +982,11 @@ void GameSave::readPSv(char * data, int dataLength) for (x=x0; x= dataLength) - goto corrupt; + throw ParseException(ParseException::Corrupt, "Not enough data at line " MTOS(__LINE__) " in " MTOS(__FILE__)); j=d[p++]; if (j >= PT_NUM) { //TODO: Possibly some server side translation - j = PT_DUST;//goto corrupt; + j = PT_DUST;//throw ParseException(ParseException::Corrupt, "Not enough data at line " MTOS(__LINE__) " in " MTOS(__FILE__)); } if (j) { @@ -955,7 +1017,7 @@ void GameSave::readPSv(char * data, int dataLength) { i--; if (p+1 >= dataLength) - goto corrupt; + throw ParseException(ParseException::Corrupt, "Not enough data at line " MTOS(__LINE__) " in " MTOS(__FILE__)); if (i < NPART) { particles[i].vx = (d[p++]-127.0f)/16.0f; @@ -972,7 +1034,7 @@ void GameSave::readPSv(char * data, int dataLength) { if (ver>=44) { if (p >= dataLength) { - goto corrupt; + throw ParseException(ParseException::Corrupt, "Not enough data at line " MTOS(__LINE__) " in " MTOS(__FILE__)); } if (i <= NPART) { ttv = (d[p++])<<8; @@ -983,7 +1045,7 @@ void GameSave::readPSv(char * data, int dataLength) } } else { if (p >= dataLength) - goto corrupt; + throw ParseException(ParseException::Corrupt, "Not enough data at line " MTOS(__LINE__) " in " MTOS(__FILE__)); if (i <= NPART) particles[i-1].life = d[p++]*4; else @@ -998,7 +1060,7 @@ void GameSave::readPSv(char * data, int dataLength) if (i) { if (p >= dataLength) { - goto corrupt; + throw ParseException(ParseException::Corrupt, "Not enough data at line " MTOS(__LINE__) " in " MTOS(__FILE__)); } if (i <= NPART) { ttv = (d[p++])<<8; @@ -1028,7 +1090,7 @@ void GameSave::readPSv(char * data, int dataLength) if (i && (ty==PT_PBCN || (ty==PT_TRON && ver>=77))) { if (p >= dataLength) - goto corrupt; + throw ParseException(ParseException::Corrupt, "Not enough data at line " MTOS(__LINE__) " in " MTOS(__FILE__)); if (i <= NPART) particles[i-1].tmp2 = d[p++]; else @@ -1044,7 +1106,7 @@ void GameSave::readPSv(char * data, int dataLength) { if (ver>=49) { if (p >= dataLength) { - goto corrupt; + throw ParseException(ParseException::Corrupt, "Not enough data at line " MTOS(__LINE__) " in " MTOS(__FILE__)); } if (i <= NPART) { particles[i-1].dcolour = d[p++]<<24; @@ -1062,7 +1124,7 @@ void GameSave::readPSv(char * data, int dataLength) { if (ver>=49) { if (p >= dataLength) { - goto corrupt; + throw ParseException(ParseException::Corrupt, "Not enough data at line " MTOS(__LINE__) " in " MTOS(__FILE__)); } if (i <= NPART) { particles[i-1].dcolour |= d[p++]<<16; @@ -1080,7 +1142,7 @@ void GameSave::readPSv(char * data, int dataLength) { if (ver>=49) { if (p >= dataLength) { - goto corrupt; + throw ParseException(ParseException::Corrupt, "Not enough data at line " MTOS(__LINE__) " in " MTOS(__FILE__)); } if (i <= NPART) { particles[i-1].dcolour |= d[p++]<<8; @@ -1098,7 +1160,7 @@ void GameSave::readPSv(char * data, int dataLength) { if (ver>=49) { if (p >= dataLength) { - goto corrupt; + throw ParseException(ParseException::Corrupt, "Not enough data at line " MTOS(__LINE__) " in " MTOS(__FILE__)); } if (i <= NPART) { particles[i-1].dcolour |= d[p++]; @@ -1118,7 +1180,7 @@ void GameSave::readPSv(char * data, int dataLength) { if (p >= dataLength) { - goto corrupt; + throw ParseException(ParseException::Corrupt, "Not enough data at line " MTOS(__LINE__) " in " MTOS(__FILE__)); } if (i <= NPART) { @@ -1160,7 +1222,7 @@ void GameSave::readPSv(char * data, int dataLength) if (i && (ty==PT_CLNE || (ty==PT_PCLN && ver>=43) || (ty==PT_BCLN && ver>=44) || (ty==PT_SPRK && ver>=21) || (ty==PT_LAVA && ver>=34) || (ty==PT_PIPE && ver>=43) || (ty==PT_LIFE && ver>=51) || (ty==PT_PBCN && ver>=52) || (ty==PT_WIRE && ver>=55) || (ty==PT_STOR && ver>=59) || (ty==PT_CONV && ver>=60))) { if (p >= dataLength) - goto corrupt; + throw ParseException(ParseException::Corrupt, "Not enough data at line " MTOS(__LINE__) " in " MTOS(__FILE__)); if (i <= NPART) particles[i-1].ctype = d[p++]; else @@ -1238,7 +1300,7 @@ void GameSave::readPSv(char * data, int dataLength) for (i=0; i dataLength) - goto corrupt; + throw ParseException(ParseException::Corrupt, "Not enough data at line " MTOS(__LINE__) " in " MTOS(__FILE__)); x = d[p++]; x |= ((unsigned)d[p++])<<8; tempSign.x = x+x0; @@ -1249,7 +1311,7 @@ void GameSave::readPSv(char * data, int dataLength) tempSign.ju = (sign::Justification)x; x = d[p++]; if (p+x > dataLength) - goto corrupt; + throw ParseException(ParseException::Corrupt, "Not enough data at line " MTOS(__LINE__) " in " MTOS(__FILE__)); if(x>254) x = 254; memcpy(tempSignText, d+p, x); @@ -1265,20 +1327,44 @@ void GameSave::readPSv(char * data, int dataLength) break; signs.push_back(tempSigns[i]); } + + } + catch(ParseException & e) + { + if (m) + { + free(m); + m = 0; + } + if (d) + { + free(d); + d = 0; + } + if (fp) + { + free(fp); + fp = 0; + } + throw; + } -version1: - if (m) free(m); - if (d) free(d); - if (fp) free(fp); - - return; - -corrupt: - if (m) free(m); - if (d) free(d); - if (fp) free(fp); - - throw ParseException(ParseException::Corrupt, "Save data corrupt"); + version1: + if (m) + { + free(m); + m = 0; + } + if (d) + { + free(d); + d = 0; + } + if (fp) + { + free(fp); + fp = 0; + } } char * GameSave::serialiseOPS(int & dataLength) diff --git a/src/game/GameView.cpp b/src/game/GameView.cpp index 4f9c41a01..69beb7594 100644 --- a/src/game/GameView.cpp +++ b/src/game/GameView.cpp @@ -850,6 +850,9 @@ void GameView::OnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool case '`': c->ShowConsole(); break; + case 'e': + c->OpenElementSearch(); + break; case 'f': c->FrameStep(); break; diff --git a/src/game/ToolButton.cpp b/src/game/ToolButton.cpp index 5c9f2d455..729530993 100644 --- a/src/game/ToolButton.cpp +++ b/src/game/ToolButton.cpp @@ -38,7 +38,7 @@ void ToolButton::OnMouseUp(int x, int y, unsigned int button) void ToolButton::Draw(const ui::Point& screenPos) { Graphics * g = ui::Engine::Ref().g; - int totalColour = Appearance.BackgroundInactive.Red + (3*Appearance.BackgroundInactive.Green) + (2*Appearance.BackgroundInactive.Blue); + int totalColour = Appearance.BackgroundInactive.Blue + (3*Appearance.BackgroundInactive.Green) + (2*Appearance.BackgroundInactive.Red); g->fillrect(screenPos.X+2, screenPos.Y+2, Size.X-4, Size.Y-4, Appearance.BackgroundInactive.Red, Appearance.BackgroundInactive.Green, Appearance.BackgroundInactive.Blue, Appearance.BackgroundInactive.Alpha); diff --git a/src/interface/Label.cpp b/src/interface/Label.cpp index 35b20007e..76ea45f84 100644 --- a/src/interface/Label.cpp +++ b/src/interface/Label.cpp @@ -48,40 +48,51 @@ void Label::SetText(std::string text) void Label::updateMultiline() { - char * rawText = new char[text.length()+1]; - std::copy(text.begin(), text.end(), rawText); - rawText[text.length()] = 0; - int lines = 1; - int currentWidth = 0; - char * lastSpace = NULL; - char * currentWord = rawText; - char * nextSpace; - while(true) + if(text.length()>0) { - nextSpace = strchr(currentWord+1, ' '); - if(nextSpace) - nextSpace[0] = 0; - int width = Graphics::textwidth(currentWord); - if(width+currentWidth > Size.X-6) + char * rawText = new char[text.length()+1]; + std::copy(text.begin(), text.end(), rawText); + rawText[text.length()] = 0; + + int currentWidth = 0; + char * lastSpace = NULL; + char * currentWord = rawText; + char * nextSpace; + while(true) { - currentWidth = width; - currentWord[0] = '\n'; - lines++; + nextSpace = strchr(currentWord+1, ' '); + if(nextSpace) + nextSpace[0] = 0; + int width = Graphics::textwidth(currentWord); + if(width+currentWidth > Size.X-6) + { + currentWidth = width; + currentWord[0] = '\n'; + lines++; + } + else + currentWidth += width; + if(nextSpace) + nextSpace[0] = ' '; + if(!currentWord[0] || !currentWord[1] || !(currentWord = strchr(currentWord+1, ' '))) + break; } - else - currentWidth += width; - if(nextSpace) - nextSpace[0] = ' '; - if(!(currentWord = strchr(currentWord+1, ' '))) - break; + if(autoHeight) + { + Size.Y = lines*12; + } + textLines = std::string(rawText); + delete[] rawText; } - if(autoHeight) + else { - Size.Y = lines*12; + if(autoHeight) + { + Size.Y = 12; + } + textLines = std::string(""); } - textLines = std::string(rawText); - delete[] rawText; } std::string Label::GetText() diff --git a/src/interface/Textbox.cpp b/src/interface/Textbox.cpp index 7d939fd64..fbe3c6b21 100644 --- a/src/interface/Textbox.cpp +++ b/src/interface/Textbox.cpp @@ -244,6 +244,8 @@ void Textbox::Draw(const Point& screenPos) } if(border) g->drawrect(screenPos.X, screenPos.Y, Size.X, Size.Y, 160, 160, 160, 255); } + if(Appearance.icon) + g->draw_icon(screenPos.X+iconPosition.X, screenPos.Y+iconPosition.Y, Appearance.icon); } /* diff --git a/src/preview/PreviewView.cpp b/src/preview/PreviewView.cpp index 79d2cddf3..ff708c66e 100644 --- a/src/preview/PreviewView.cpp +++ b/src/preview/PreviewView.cpp @@ -216,7 +216,7 @@ void PreviewView::OnDraw() g->draw_image(savePreview->Data, (Position.X+1)+(((XRES/2)-savePreview->Size.X)/2), (Position.Y+1)+(((YRES/2)-savePreview->Size.Y)/2), savePreview->Size.X, savePreview->Size.Y, 255); } g->drawrect(Position.X, Position.Y, (XRES/2)+1, (YRES/2)+1, 255, 255, 255, 100); - g->draw_line(Position.X+1+XRES/2, Position.Y+1, Position.X+XRES/2, Position.Y+Size.Y-2, 200, 200, 200, 255); + g->draw_line(Position.X+1+XRES/2, Position.Y+1, Position.X+1+XRES/2, Position.Y+Size.Y-2, 200, 200, 200, 255); g->draw_line(Position.X+1, Position.Y+12+YRES/2, Position.X-1+XRES/2, Position.Y+12+YRES/2, 100, 100, 100,255); @@ -509,6 +509,7 @@ void PreviewView::NotifyCommentsChanged(PreviewModel * sender) tempUsername->Appearance.VerticalAlign = ui::Appearance::AlignBottom; maxY += 16; tempComment = new ui::Label(ui::Point(0, 0), ui::Point(Size.X-((XRES/2) + 10), -1), comments[i].comment); + tempComment->SetMultiline(true); tempComment->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; tempComment->Appearance.VerticalAlign = ui::Appearance::AlignTop; tempComment->SetTextColour(ui::Colour(180, 180, 180));