diff --git a/resources/bspguy.cfg b/resources/bspguy.cfg index d8d81e72..4318a694 100644 --- a/resources/bspguy.cfg +++ b/resources/bspguy.cfg @@ -3,7 +3,7 @@ window_height=480 window_x=300 window_y=300 window_maximized=0 -save_windows=0 +save_windows=1 debug_open=0 keyvalue_open=0 transform_open=0 @@ -83,4 +83,5 @@ MAX_MAP_TEXTURES=4096 MAX_MAP_LIGHTDATA=64 MAX_TEXTURE_DIMENSION=1024 TEXTURE_STEP=16 -language=EN \ No newline at end of file +language=EN +palette=quake_1 \ No newline at end of file diff --git a/resources/languages/language.ini b/resources/languages/language.ini index 78aa3d46..4418434d 100644 --- a/resources/languages/language.ini +++ b/resources/languages/language.ini @@ -101,8 +101,8 @@ LANG_0099 = Using extended marksurfaces [32 bit]\n LANG_0100 = Using extended edges [32 bit]\n LANG_0101 = mem size : {} - {} - {} or {}\n LANG_0102 = lighting: {}\n -LANG_0103 = {}.bsp ent data (line {}): Unexpected '{'\n -LANG_0104 = {}.bsp ent data (line {}): Unexpected '}'\n +LANG_0103 = {}.bsp ent data (line {}): Unexpected '{{'\n +LANG_0104 = {}.bsp ent data (line {}): Unexpected '}}'\n LANG_0105 = Found unknown classname entity. Skip it.\n LANG_0106 = First entity has classname different from 'woldspawn', we do fixup it\n LANG_0107 = {:>12} diff --git a/resources/languages/language_ru.ini b/resources/languages/language_ru.ini index 26571292..e66c74f4 100644 --- a/resources/languages/language_ru.ini +++ b/resources/languages/language_ru.ini @@ -101,8 +101,8 @@ LANG_0099 = Используются расширенные марк-сурфе LANG_0100 = Используются расширенные рёбра [32 бита]\n LANG_0101 = размера памяти: {} - {} - {} или {}\n LANG_0102 = освещения: {}\n -LANG_0103 = Список сущностей {}.bsp (строка {}): Неожиданный символ '{'\n -LANG_0104 = Список сущностей {}.bsp (строка {}): Неожиданный символ '}'\n +LANG_0103 = Список сущностей {}.bsp (строка {}): Неожиданный символ '{{'\n +LANG_0104 = Список сущностей {}.bsp (строка {}): Неожиданный символ '}}'\n LANG_0105 = Найдена сущность с неизвестным классом. Пропущено.\n LANG_0106 = Первая сущность имеет класс, отличный от 'worldspawn', исправляем\n LANG_0107 = {:>12} diff --git a/resources/palettes/half_life.pal b/resources/palettes/half_life.pal new file mode 100644 index 00000000..1a8b9feb Binary files /dev/null and b/resources/palettes/half_life.pal differ diff --git a/resources/palettes/laser_arena.pal b/resources/palettes/laser_arena.pal new file mode 100644 index 00000000..618989f0 Binary files /dev/null and b/resources/palettes/laser_arena.pal differ diff --git a/resources/palettes/quake_1.pal b/resources/palettes/quake_1.pal new file mode 100644 index 00000000..7eefda1d Binary files /dev/null and b/resources/palettes/quake_1.pal differ diff --git a/src/bsp/Bsp.cpp b/src/bsp/Bsp.cpp index 2ebe8c6d..31c92be2 100644 --- a/src/bsp/Bsp.cpp +++ b/src/bsp/Bsp.cpp @@ -173,6 +173,7 @@ Bsp::Bsp(std::string fpath) is_broken_clipnodes = false; is_blue_shift = false; is_colored_lightmap = true; + is_texture_pal = true; force_skip_crc = false; @@ -1177,16 +1178,6 @@ bool Bsp::should_resize_lightmap(LIGHTMAP& oldLightmap, LIGHTMAP& newLightmap) return false; } -int Bsp::get_new_lightmaps_data_size() -{ - int tmpLightDataSz = 0; - for (int i = 0; i < faceCount; i++) { - int size[2]; - GetFaceLightmapSize(this, i, size); - tmpLightDataSz += size[0] * size[1] * sizeof(COLOR3) * lightmap_count(i); - } - return tmpLightDataSz; -} void Bsp::resize_all_lightmaps(bool logged) { @@ -3599,79 +3590,57 @@ bool Bsp::load_lumps(std::string fpath) update_lump_pointers(); - int iFirstFace = -1; - int nOffseLight = 0; - for (int i = faceCount - 1; i >= 0; i--) + int lightmap3_bytes = 0; + for (int i = 0; i < faceCount; i++) { - BSPFACE32& face = faces[i]; - if (face.nLightmapOffset >= 0 && face.nLightmapOffset < bsp_header.lump[LUMP_LIGHTING].nLength) + if (faces[i].nLightmapOffset >= 0) { - iFirstFace = i; - nOffseLight = face.nLightmapOffset; - break; + lightmap3_bytes += GetFaceLightmapSizeBytes(this, i); } } - int iNextFace = -1; - int nNextOffseLight = lightDataLength; + int lightmap1_bytes = lightmap3_bytes / 3; + is_colored_lightmap = lightdata == NULL || abs(lightmap1_bytes - lightDataLength) > abs(lightmap3_bytes - lightDataLength); - for (int i = iFirstFace - 1; i >= 0; i--) - { - BSPFACE32& face = faces[i]; - if (face.nLightmapOffset >= 0 && face.nLightmapOffset < bsp_header.lump[LUMP_LIGHTING].nLength) - { - if (abs(face.nLightmapOffset - nOffseLight) < abs(nNextOffseLight - nOffseLight)) - { - nNextOffseLight = face.nLightmapOffset; - iNextFace = i; - } - } - } + if (g_settings.verboseLogs) + print_log(get_localized_string(LANG_0102), !is_colored_lightmap ? "monochrome" : "colored"); - float fLightSamples = is_bsp2 || is_bsp2_old || is_bsp29 ? 1.0f : 3.0f; - //print_log("{} {} {} -> {}\n", is_bsp2, is_bsp2_old, is_bsp29, fLightSamples); - if (fLightSamples < 3.0 && iNextFace >= 0 && iFirstFace >= 0 && iFirstFace != iNextFace) + int textures_bytes = 0; + int textures_no_pal_bytes = 0; + + for (int t = 0; t < textureCount; t++) { - float face1light = GetFaceLightmapSizeBytes(this, iFirstFace) / (float)sizeof(COLOR3); - float face2light = GetFaceLightmapSizeBytes(this, iNextFace) / (float)sizeof(COLOR3); + int iStartOffset = ((int*)textures)[t + 1]; - int memsize = abs(nOffseLight - nNextOffseLight); + if (iStartOffset < 0 || iStartOffset + (int)sizeof(BSPMIPTEX) > textureDataLength) + continue; - if (iFirstFace > iNextFace) - { - fLightSamples = memsize / face1light; - } - else if (iNextFace > iFirstFace) - { - fLightSamples = memsize / face2light; - } + BSPMIPTEX* tex = ((BSPMIPTEX*)(textures + iStartOffset)); + if (tex->nOffsets[0] > textureDataLength) + continue; - //print_log(get_localized_string(LANG_0101),fLightSamples,memsize,face1light,face2light); + textures_bytes += sizeof(BSPMIPTEX); + textures_no_pal_bytes += sizeof(BSPMIPTEX); - if (abs(fLightSamples - (int)fLightSamples) > 0.01f) + if (tex->nOffsets[0] > 0) { - memsize = (memsize + 3) & ~3; - if (iFirstFace > iNextFace) - { - fLightSamples = memsize / face1light; - } - else if (iNextFace > iFirstFace) + textures_bytes += sizeof(short); + textures_no_pal_bytes += sizeof(short); + + textures_bytes += sizeof(COLOR3) * 256; + + for (int i = 0; i < MIPLEVELS; i++) { - fLightSamples = memsize / face2light; + textures_bytes += (tex->nWidth >> i) * (tex->nHeight >> i); + textures_no_pal_bytes += (tex->nWidth >> i) * (tex->nHeight >> i); } - //print_log(get_localized_string(LANG_1021),fLightSamples,memsize,face1light,face2light); } } - int tmp_is_colored_lightmap = (int)round(fLightSamples); - if (tmp_is_colored_lightmap < 1) - tmp_is_colored_lightmap = 1; - - is_colored_lightmap = tmp_is_colored_lightmap > 1; - + is_texture_pal = textureCount == 0 || textures_no_pal_bytes == textures_bytes || abs(textures_no_pal_bytes - textureDataLength) > abs(textures_bytes - textureDataLength);; if (g_settings.verboseLogs) - print_log(get_localized_string(LANG_0102), !is_colored_lightmap ? "monochrome" : "colored"); + print_log("Embedded Textures: {}\n", !is_texture_pal ? "quake pal" : "has pal"); if (!is_colored_lightmap) { @@ -5331,7 +5300,7 @@ int Bsp::add_texture(const char* oldname, unsigned char* data, int width, int he if (is_bsp2 || is_bsp29 || force_quake_pal) { if (!custompal) - memcpy(palette, quakeDefaultPalette, 256 * sizeof(COLOR3)); + memcpy(palette, g_settings.palette_data, 256 * sizeof(COLOR3)); Quantizer* tmpCQuantizer = new Quantizer(256, 8); tmpCQuantizer->SetColorTable(palette, 256); tmpCQuantizer->ApplyColorTable((COLOR3*)data, width * height); @@ -7762,7 +7731,7 @@ void Bsp::ExportToObjWIP(const std::string& path, ExportObjOrder order, int isca { if (texOffset >= 0) { - COLOR3* imageData = ConvertMipTexToRGB(((BSPMIPTEX*)(textures + texOffset)), is_texture_with_pal(texinfo.iMiptex) ? NULL : (COLOR3*)quakeDefaultPalette); + COLOR3* imageData = ConvertMipTexToRGB(((BSPMIPTEX*)(textures + texOffset)), is_texture_with_pal(texinfo.iMiptex) ? NULL : (COLOR3*)g_settings.palette_data); for (int k = 0; k < tex.nHeight * tex.nWidth; k++) { @@ -8449,44 +8418,15 @@ bool Bsp::is_texture_with_pal(int textureid) if (textureid < 0 || textureid >= textureCount) return false; - if (bsp_header.nVersion == 30) - return true; int iStartOffset = ((int*)textures)[textureid + 1]; - unsigned char* pStartOffset = (unsigned char*)textures + iStartOffset; - unsigned char* pEndOffset = (unsigned char*)textures + textureDataLength; - if (iStartOffset >= 0) { - for (int i = 0; i < textureCount; i++) - { - int iCurOffset = ((int*)textures)[i + 1]; - if (iCurOffset < 0 || i == textureid || iCurOffset == iStartOffset) - { - continue; - } - - unsigned char* pCurOffset = (unsigned char*)textures + iCurOffset; - - if (pCurOffset < pEndOffset && pCurOffset > pStartOffset) - { - pEndOffset = pCurOffset; - } - } - BSPMIPTEX* tex = ((BSPMIPTEX*)(textures + iStartOffset)); if (tex->nOffsets[0] <= 0) // wad texture return true; - - int lastMipSize = (tex->nWidth / 8) * (tex->nHeight / 8); - unsigned char* palOffset = pStartOffset + tex->nOffsets[3] + lastMipSize; - - if (abs(palOffset - pEndOffset) >= sizeof(COLOR3) * 256) - { - return true; - } } - return false; + return is_texture_pal; } \ No newline at end of file diff --git a/src/bsp/Bsp.h b/src/bsp/Bsp.h index cca82da6..e39ebd41 100644 --- a/src/bsp/Bsp.h +++ b/src/bsp/Bsp.h @@ -97,6 +97,7 @@ class Bsp BSPMODEL* models; bool is_colored_lightmap; + bool is_texture_pal; std::string bsp_path; std::string bsp_name; @@ -333,7 +334,6 @@ class Bsp void save_undo_lightmaps(bool logged = false); void resize_all_lightmaps(bool logged = false); bool should_resize_lightmap(LIGHTMAP& oldLightmap, LIGHTMAP& newLightmap); - int get_new_lightmaps_data_size(); private: unsigned int remove_unused_lightmaps(bool* usedFaces); diff --git a/src/bsp/Wad.h b/src/bsp/Wad.h index ab9786d4..b541bdea 100644 --- a/src/bsp/Wad.h +++ b/src/bsp/Wad.h @@ -136,56 +136,3 @@ COLOR4* ConvertMipTexToRGBA(BSPMIPTEX* tex, COLOR3* palette = NULL); COLOR3 GetMipTexAplhaColor(BSPMIPTEX* wadTex, COLOR3* palette = NULL); COLOR3 GetWadTexAplhaColor(WADTEX* wadTex, COLOR3* palette = NULL); - -const unsigned char quakeDefaultPalette[768] = -{ -0,0,0,15,15,15,31,31,31,47,47,47,63,63,63,75,75,75,91,91,91,107,107,107,123,123,123,139,139,139,155,155,155,171, -171,171,187,187,187,203,203,203,219,219,219,235,235,235,15,11,7,23,15,11,31,23,11,39,27,15,47,35,19,55,43,23,63, -47,23,75,55,27,83,59,27,91,67,31,99,75,31,107,83,31,115,87,31,123,95,35,131,103,35,143,111,35,11,11,15,19,19,27, -27,27,39,39,39,51,47,47,63,55,55,75,63,63,87,71,71,103,79,79,115,91,91,127,99,99,139,107,107,151,115,115,163,123, -123,175,131,131,187,139,139,203,0,0,0,7,7,0,11,11,0,19,19,0,27,27,0,35,35,0,43,43,7,47,47,7,55,55,7,63,63,7,71,71, -7,75,75,11,83,83,11,91,91,11,99,99,11,107,107,15,7,0,0,15,0,0,23,0,0,31,0,0,39,0,0,47,0,0,55,0,0,63,0,0,71,0,0,79, -0,0,87,0,0,95,0,0,103,0,0,111,0,0,119,0,0,127,0,0,19,19,0,27,27,0,35,35,0,47,43,0,55,47,0,67,55,0,75,59,7,87,67,7, -95,71,7,107,75,11,119,83,15,131,87,19,139,91,19,151,95,27,163,99,31,175,103,35,35,19,7,47,23,11,59,31,15,75,35,19, -87,43,23,99,47,31,115,55,35,127,59,43,143,67,51,159,79,51,175,99,47,191,119,47,207,143,43,223,171,39,239,203,31,255, -243,27,11,7,0,27,19,0,43,35,15,55,43,19,71,51,27,83,55,35,99,63,43,111,71,51,127,83,63,139,95,71,155,107,83,167,123, -95,183,135,107,195,147,123,211,163,139,227,179,151,171,139,163,159,127,151,147,115,135,139,103,123,127,91,111,119, -83,99,107,75,87,95,63,75,87,55,67,75,47,55,67,39,47,55,31,35,43,23,27,35,19,19,23,11,11,15,7,7,187,115,159,175,107, -143,163,95,131,151,87,119,139,79,107,127,75,95,115,67,83,107,59,75,95,51,63,83,43,55,71,35,43,59,31,35,47,23,27,35, -19,19,23,11,11,15,7,7,219,195,187,203,179,167,191,163,155,175,151,139,163,135,123,151,123,111,135,111,95,123,99,83, -107,87,71,95,75,59,83,63,51,67,51,39,55,43,31,39,31,23,27,19,15,15,11,7,111,131,123,103,123,111,95,115,103,87,107, -95,79,99,87,71,91,79,63,83,71,55,75,63,47,67,55,43,59,47,35,51,39,31,43,31,23,35,23,15,27,19,11,19,11,7,11,7,255, -243,27,239,223,23,219,203,19,203,183,15,187,167,15,171,151,11,155,131,7,139,115,7,123,99,7,107,83,0,91,71,0,75,55, -0,59,43,0,43,31,0,27,15,0,11,7,0,0,0,255,11,11,239,19,19,223,27,27,207,35,35,191,43,43,175,47,47,159,47,47,143,47, -47,127,47,47,111,47,47,95,43,43,79,35,35,63,27,27,47,19,19,31,11,11,15,43,0,0,59,0,0,75,7,0,95,7,0,111,15,0,127,23, -7,147,31,7,163,39,11,183,51,15,195,75,27,207,99,43,219,127,59,227,151,79,231,171,95,239,191,119,247,211,139,167,123, -59,183,155,55,199,195,55,231,227,87,127,191,255,171,231,255,215,255,255,103,0,0,139,0,0,179,0,0,215,0,0,255,0,0,255, -243,147,255,247,199,255,255,255,159,91,83 -}; - - -const unsigned char halflifeDefaultPalette[768] = -{ -0,0,0,15,15,15,31,31,31,47,47,47,63,63,63,75,75,75,91,91,91,107,107,107,123,123,123,139,139,139,155,155,155,171, -171,171,187,187,187,203,203,203,219,219,219,235,235,235,15,11,7,23,15,11,31,23,11,39,27,15,47,35,19,55,43,23,63, -47,23,75,55,27,83,59,27,91,67,31,99,75,31,107,83,31,115,87,31,123,95,35,131,103,35,143,111,35,11,11,15,19,19,27, -27,27,39,39,39,51,47,47,63,55,55,75,63,63,87,71,71,103,79,79,115,91,91,127,99,99,139,107,107,151,115,115,163,123, -123,175,131,131,187,139,139,203,0,0,0,7,7,0,11,11,0,19,19,0,27,27,0,35,35,0,43,43,7,47,47,7,55,55,7,63,63,7,71,71, -7,75,75,11,83,83,11,91,91,11,99,99,11,107,107,15,7,0,0,15,0,0,23,0,0,31,0,0,39,0,0,47,0,0,55,0,0,63,0,0,71,0,0,79, -0,0,87,0,0,95,0,0,103,0,0,111,0,0,119,0,0,127,0,0,19,19,0,27,27,0,35,35,0,47,43,0,55,47,0,67,55,0,75,59,7,87,67,7, -95,71,7,107,75,11,119,83,15,131,87,19,139,91,19,151,95,27,163,99,31,175,103,35,35,19,7,47,23,11,59,31,15,75,35,19, -87,43,23,99,47,31,115,55,35,127,59,43,143,67,51,159,79,51,175,99,47,191,119,47,207,143,43,223,171,39,239,203,31,255, -243,27,11,7,0,27,19,0,43,35,15,55,43,19,71,51,27,83,55,35,99,63,43,111,71,51,127,83,63,139,95,71,155,107,83,167,123, -95,183,135,107,195,147,123,211,163,139,227,179,151,171,139,163,159,127,151,147,115,135,139,103,123,127,91,111,119, -83,99,107,75,87,95,63,75,87,55,67,75,47,55,67,39,47,55,31,35,43,23,27,35,19,19,23,11,11,15,7,7,187,115,159,175,107, -143,163,95,131,151,87,119,139,79,107,127,75,95,115,67,83,107,59,75,95,51,63,83,43,55,71,35,43,59,31,35,47,23,27,35, -19,19,23,11,11,15,7,7,219,195,187,203,179,167,191,163,155,175,151,139,163,135,123,151,123,111,135,111,95,123,99,83, -107,87,71,95,75,59,83,63,51,67,51,39,55,43,31,39,31,23,27,19,15,15,11,7,111,131,123,103,123,111,95,115,103,87,107, -95,79,99,87,71,91,79,63,83,71,55,75,63,47,67,55,43,59,47,35,51,39,31,43,31,23,35,23,15,27,19,11,19,11,7,11,7,255, -243,27,239,223,23,219,203,19,203,183,15,187,167,15,171,151,11,155,131,7,139,115,7,123,99,7,107,83,0,91,71,0,75,55, -0,59,43,0,43,31,0,27,15,0,11,7,0,0,0,255,11,11,239,19,19,223,27,27,207,35,35,191,43,43,175,47,47,159,47,47,143,47, -47,127,47,47,111,47,47,95,43,43,79,35,35,63,27,27,47,19,19,31,11,11,15,43,0,0,59,0,0,75,7,0,95,7,0,111,15,0,127,23, -7,147,31,7,163,39,11,183,51,15,195,75,27,207,99,43,219,127,59,227,151,79,231,171,95,239,191,119,247,211,139,167,123, -59,183,155,55,199,195,55,231,227,87,0,255,0,171,231,255,215,255,255,103,0,0,139,0,0,179,0,0,215,0,0,255,0,0,255,243, -147,255,247,199,255,255,255,159,91,83 -}; diff --git a/src/editor/BspRenderer.cpp b/src/editor/BspRenderer.cpp index 1a90cf9c..7bb685b7 100644 --- a/src/editor/BspRenderer.cpp +++ b/src/editor/BspRenderer.cpp @@ -381,7 +381,7 @@ void BspRenderer::loadTextures() } else { - imageData = ConvertMipTexToRGB(tex, map->is_texture_with_pal(i) ? NULL : (COLOR3*)quakeDefaultPalette); + imageData = ConvertMipTexToRGB(tex, map->is_texture_with_pal(i) ? NULL : (COLOR3*)g_settings.palette_data); embedCount++; } diff --git a/src/editor/Gui.cpp b/src/editor/Gui.cpp index d35c5171..774842c3 100644 --- a/src/editor/Gui.cpp +++ b/src/editor/Gui.cpp @@ -2780,8 +2780,6 @@ void Gui::drawMenuBar() if (ImGui::BeginMenu("Delete cull faces", map)) { - int leafIdx = 0; - if (ImGui::MenuItem("Delete from [SKY LEAFS]")) { map->remove_faces_by_content(CONTENTS_SKY); @@ -5840,6 +5838,7 @@ void Gui::drawSettings() bool oldShowSettings = showSettingsWidget; bool apply_settings_pressed = false; static std::string langForSelect = g_settings.selected_lang; + static std::string palForSelect = g_settings.palette_name; if (ImGui::Begin(fmt::format("{}###SETTING_WIDGET", get_localized_string(LANG_1114)).c_str(), &showSettingsWidget)) { @@ -6065,6 +6064,8 @@ void Gui::drawSettings() ImGui::EndTooltip(); } ImGui::Separator(); + ImGui::TextUnformatted("Language:"); + ImGui::SameLine(); if (ImGui::BeginCombo("##lang", langForSelect.c_str())) { for (const auto& s : g_settings.languages) @@ -6077,6 +6078,20 @@ void Gui::drawSettings() ImGui::EndCombo(); } ImGui::Separator(); + ImGui::TextUnformatted("Palette:"); + ImGui::SameLine(); + if (ImGui::BeginCombo("##pal", palForSelect.c_str())) + { + for (const auto& s : g_settings.palettes) + { + if (ImGui::Selectable(s.name.c_str(), s.name == palForSelect)) + { + palForSelect = s.name; + } + } + ImGui::EndCombo(); + } + ImGui::Separator(); if (ImGui::Button(get_localized_string(LANG_0739).c_str())) { g_settings.reset(); @@ -6592,6 +6607,7 @@ void Gui::drawSettings() if (oldShowSettings && !showSettingsWidget || apply_settings_pressed) { g_settings.selected_lang = langForSelect; + g_settings.palette_name = palForSelect; set_localize_lang(g_settings.selected_lang); g_settings.save(); if (!app->reloading) diff --git a/src/editor/Settings.cpp b/src/editor/Settings.cpp index 0cb8f3bb..d12eb394 100644 --- a/src/editor/Settings.cpp +++ b/src/editor/Settings.cpp @@ -88,6 +88,61 @@ void AppSettings::loadDefault() entListReload = true; stripWad = false; + palette_name = "quake_1"; + + unsigned char default_data[0x300] = { + 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x1F, 0x1F, 0x1F, 0x2F, 0x2F, 0x2F, 0x3F, 0x3F, 0x3F, 0x4B, + 0x4B, 0x4B, 0x5B, 0x5B, 0x5B, 0x6B, 0x6B, 0x6B, 0x7B, 0x7B, 0x7B, 0x8B, 0x8B, 0x8B, 0x9B, 0x9B, + 0x9B, 0xAB, 0xAB, 0xAB, 0xBB, 0xBB, 0xBB, 0xCB, 0xCB, 0xCB, 0xDB, 0xDB, 0xDB, 0xEB, 0xEB, 0xEB, + 0x0F, 0x0B, 0x07, 0x17, 0x0F, 0x0B, 0x1F, 0x17, 0x0B, 0x27, 0x1B, 0x0F, 0x2F, 0x23, 0x13, 0x37, + 0x2B, 0x17, 0x3F, 0x2F, 0x17, 0x4B, 0x37, 0x1B, 0x53, 0x3B, 0x1B, 0x5B, 0x43, 0x1F, 0x63, 0x4B, + 0x1F, 0x6B, 0x53, 0x1F, 0x73, 0x57, 0x1F, 0x7B, 0x5F, 0x23, 0x83, 0x67, 0x23, 0x8F, 0x6F, 0x23, + 0x0B, 0x0B, 0x0F, 0x13, 0x13, 0x1B, 0x1B, 0x1B, 0x27, 0x27, 0x27, 0x33, 0x2F, 0x2F, 0x3F, 0x37, + 0x37, 0x4B, 0x3F, 0x3F, 0x57, 0x47, 0x47, 0x67, 0x4F, 0x4F, 0x73, 0x5B, 0x5B, 0x7F, 0x63, 0x63, + 0x8B, 0x6B, 0x6B, 0x97, 0x73, 0x73, 0xA3, 0x7B, 0x7B, 0xAF, 0x83, 0x83, 0xBB, 0x8B, 0x8B, 0xCB, + 0x00, 0x00, 0x00, 0x07, 0x07, 0x00, 0x0B, 0x0B, 0x00, 0x13, 0x13, 0x00, 0x1B, 0x1B, 0x00, 0x23, + 0x23, 0x00, 0x2B, 0x2B, 0x07, 0x2F, 0x2F, 0x07, 0x37, 0x37, 0x07, 0x3F, 0x3F, 0x07, 0x47, 0x47, + 0x07, 0x4B, 0x4B, 0x0B, 0x53, 0x53, 0x0B, 0x5B, 0x5B, 0x0B, 0x63, 0x63, 0x0B, 0x6B, 0x6B, 0x0F, + 0x07, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x17, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x27, 0x00, 0x00, 0x2F, + 0x00, 0x00, 0x37, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x47, 0x00, 0x00, 0x4F, 0x00, 0x00, 0x57, 0x00, + 0x00, 0x5F, 0x00, 0x00, 0x67, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x77, 0x00, 0x00, 0x7F, 0x00, 0x00, + 0x13, 0x13, 0x00, 0x1B, 0x1B, 0x00, 0x23, 0x23, 0x00, 0x2F, 0x2B, 0x00, 0x37, 0x2F, 0x00, 0x43, + 0x37, 0x00, 0x4B, 0x3B, 0x07, 0x57, 0x43, 0x07, 0x5F, 0x47, 0x07, 0x6B, 0x4B, 0x0B, 0x77, 0x53, + 0x0F, 0x83, 0x57, 0x13, 0x8B, 0x5B, 0x13, 0x97, 0x5F, 0x1B, 0xA3, 0x63, 0x1F, 0xAF, 0x67, 0x23, + 0x23, 0x13, 0x07, 0x2F, 0x17, 0x0B, 0x3B, 0x1F, 0x0F, 0x4B, 0x23, 0x13, 0x57, 0x2B, 0x17, 0x63, + 0x2F, 0x1F, 0x73, 0x37, 0x23, 0x7F, 0x3B, 0x2B, 0x8F, 0x43, 0x33, 0x9F, 0x4F, 0x33, 0xAF, 0x63, + 0x2F, 0xBF, 0x77, 0x2F, 0xCF, 0x8F, 0x2B, 0xDF, 0xAB, 0x27, 0xEF, 0xCB, 0x1F, 0xFF, 0xF3, 0x1B, + 0x0B, 0x07, 0x00, 0x1B, 0x13, 0x00, 0x2B, 0x23, 0x0F, 0x37, 0x2B, 0x13, 0x47, 0x33, 0x1B, 0x53, + 0x37, 0x23, 0x63, 0x3F, 0x2B, 0x6F, 0x47, 0x33, 0x7F, 0x53, 0x3F, 0x8B, 0x5F, 0x47, 0x9B, 0x6B, + 0x53, 0xA7, 0x7B, 0x5F, 0xB7, 0x87, 0x6B, 0xC3, 0x93, 0x7B, 0xD3, 0xA3, 0x8B, 0xE3, 0xB3, 0x97, + 0xAB, 0x8B, 0xA3, 0x9F, 0x7F, 0x97, 0x93, 0x73, 0x87, 0x8B, 0x67, 0x7B, 0x7F, 0x5B, 0x6F, 0x77, + 0x53, 0x63, 0x6B, 0x4B, 0x57, 0x5F, 0x3F, 0x4B, 0x57, 0x37, 0x43, 0x4B, 0x2F, 0x37, 0x43, 0x27, + 0x2F, 0x37, 0x1F, 0x23, 0x2B, 0x17, 0x1B, 0x23, 0x13, 0x13, 0x17, 0x0B, 0x0B, 0x0F, 0x07, 0x07, + 0xBB, 0x73, 0x9F, 0xAF, 0x6B, 0x8F, 0xA3, 0x5F, 0x83, 0x97, 0x57, 0x77, 0x8B, 0x4F, 0x6B, 0x7F, + 0x4B, 0x5F, 0x73, 0x43, 0x53, 0x6B, 0x3B, 0x4B, 0x5F, 0x33, 0x3F, 0x53, 0x2B, 0x37, 0x47, 0x23, + 0x2B, 0x3B, 0x1F, 0x23, 0x2F, 0x17, 0x1B, 0x23, 0x13, 0x13, 0x17, 0x0B, 0x0B, 0x0F, 0x07, 0x07, + 0xDB, 0xC3, 0xBB, 0xCB, 0xB3, 0xA7, 0xBF, 0xA3, 0x9B, 0xAF, 0x97, 0x8B, 0xA3, 0x87, 0x7B, 0x97, + 0x7B, 0x6F, 0x87, 0x6F, 0x5F, 0x7B, 0x63, 0x53, 0x6B, 0x57, 0x47, 0x5F, 0x4B, 0x3B, 0x53, 0x3F, + 0x33, 0x43, 0x33, 0x27, 0x37, 0x2B, 0x1F, 0x27, 0x1F, 0x17, 0x1B, 0x13, 0x0F, 0x0F, 0x0B, 0x07, + 0x6F, 0x83, 0x7B, 0x67, 0x7B, 0x6F, 0x5F, 0x73, 0x67, 0x57, 0x6B, 0x5F, 0x4F, 0x63, 0x57, 0x47, + 0x5B, 0x4F, 0x3F, 0x53, 0x47, 0x37, 0x4B, 0x3F, 0x2F, 0x43, 0x37, 0x2B, 0x3B, 0x2F, 0x23, 0x33, + 0x27, 0x1F, 0x2B, 0x1F, 0x17, 0x23, 0x17, 0x0F, 0x1B, 0x13, 0x0B, 0x13, 0x0B, 0x07, 0x0B, 0x07, + 0xFF, 0xF3, 0x1B, 0xEF, 0xDF, 0x17, 0xDB, 0xCB, 0x13, 0xCB, 0xB7, 0x0F, 0xBB, 0xA7, 0x0F, 0xAB, + 0x97, 0x0B, 0x9B, 0x83, 0x07, 0x8B, 0x73, 0x07, 0x7B, 0x63, 0x07, 0x6B, 0x53, 0x00, 0x5B, 0x47, + 0x00, 0x4B, 0x37, 0x00, 0x3B, 0x2B, 0x00, 0x2B, 0x1F, 0x00, 0x1B, 0x0F, 0x00, 0x0B, 0x07, 0x00, + 0x00, 0x00, 0xFF, 0x0B, 0x0B, 0xEF, 0x13, 0x13, 0xDF, 0x1B, 0x1B, 0xCF, 0x23, 0x23, 0xBF, 0x2B, + 0x2B, 0xAF, 0x2F, 0x2F, 0x9F, 0x2F, 0x2F, 0x8F, 0x2F, 0x2F, 0x7F, 0x2F, 0x2F, 0x6F, 0x2F, 0x2F, + 0x5F, 0x2B, 0x2B, 0x4F, 0x23, 0x23, 0x3F, 0x1B, 0x1B, 0x2F, 0x13, 0x13, 0x1F, 0x0B, 0x0B, 0x0F, + 0x2B, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x4B, 0x07, 0x00, 0x5F, 0x07, 0x00, 0x6F, 0x0F, 0x00, 0x7F, + 0x17, 0x07, 0x93, 0x1F, 0x07, 0xA3, 0x27, 0x0B, 0xB7, 0x33, 0x0F, 0xC3, 0x4B, 0x1B, 0xCF, 0x63, + 0x2B, 0xDB, 0x7F, 0x3B, 0xE3, 0x97, 0x4F, 0xE7, 0xAB, 0x5F, 0xEF, 0xBF, 0x77, 0xF7, 0xD3, 0x8B, + 0xA7, 0x7B, 0x3B, 0xB7, 0x9B, 0x37, 0xC7, 0xC3, 0x37, 0xE7, 0xE3, 0x57, 0x7F, 0xBF, 0xFF, 0xAB, + 0xE7, 0xFF, 0xD7, 0xFF, 0xFF, 0x67, 0x00, 0x00, 0x8B, 0x00, 0x00, 0xB3, 0x00, 0x00, 0xD7, 0x00, + 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xF3, 0x93, 0xFF, 0xF7, 0xC7, 0xFF, 0xFF, 0xFF, 0x9F, 0x5B, 0x53, + }; + + memcpy(palette_data, default_data, 0x300); + ResetBspLimits(); } @@ -180,6 +235,29 @@ void AppSettings::fillLanguages(const std::string& folderPath) } } +void AppSettings::fillPalettes(const std::string& folderPath) +{ + palettes.clear(); + for (const auto& entry : fs::directory_iterator(folderPath)) + { + if (!entry.is_directory()) { + std::string filename = entry.path().filename().string(); + if (filename.ends_with(".pal")) + { + int len; + char* data = loadFile(entry.path().string(), len); + if (data) + { + filename.pop_back(); filename.pop_back(); filename.pop_back(); filename.pop_back(); + palettes.push_back({ toUpperCase(filename), NULL }); + memcpy(palettes[palettes.size() - 1].data, data, std::min(len, 0x300)); + delete[] data; + } + } + } + } +} + void AppSettings::load() { set_localize_lang("EN"); @@ -194,6 +272,10 @@ void AppSettings::load() fillLanguages("./languages/"); + fillPalettes("./palettes/"); + + palette_name = "quake_1"; + int lines_readed = 0; std::string line; while (getline(file, line)) @@ -345,6 +427,17 @@ void AppSettings::load() g_settings.selected_lang = val; set_localize_lang(g_settings.selected_lang); } + else if (key == "palette") + { + g_settings.palette_name = val; + for (auto pal : palettes) + { + if (toLowerCase(pal.name) == toLowerCase(g_settings.palette_name)) + { + memcpy(palette_data, pal.data, sizeof(palette_data)); + } + } + } else if (key == "fgd") { if (val.find('?') == std::string::npos) @@ -637,6 +730,7 @@ void AppSettings::save(std::string path) file << "workingdir=" << g_settings.workingdir << std::endl; file << "lastdir=" << g_settings.lastdir << std::endl; file << "language=" << g_settings.selected_lang << std::endl; + file << "palette=" << g_settings.palette_name << std::endl; for (size_t i = 0; i < fgdPaths.size(); i++) { @@ -739,4 +833,11 @@ void AppSettings::save() FixupAllSystemPaths(); g_app->saveSettings(); save(g_settings_path); + for (auto pal : palettes) + { + if (toLowerCase(pal.name) == toLowerCase(g_settings.palette_name)) + { + memcpy(palette_data, pal.data, sizeof(palette_data)); + } + } } diff --git a/src/editor/Settings.h b/src/editor/Settings.h index 3234beaa..651b5545 100644 --- a/src/editor/Settings.h +++ b/src/editor/Settings.h @@ -44,6 +44,12 @@ struct PathToggleStruct } }; +struct PaletteData +{ + std::string name; + unsigned char data[0x300]; +}; + struct AppSettings { int windowWidth; @@ -69,6 +75,11 @@ struct AppSettings std::vector languages; + std::vector palettes; + std::string palette_name; + + unsigned char palette_data[0x300]; + bool settingLoaded; // Settings loaded bool verboseLogs; bool save_windows; @@ -109,8 +120,10 @@ struct AppSettings void load(); void reset(); void save(); +private: void save(std::string path); void fillLanguages(const std::string& folderPath); + void fillPalettes(const std::string& folderPath); }; extern AppSettings g_settings; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 7d42a8a9..548c33eb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -987,7 +987,7 @@ int main(int argc, char* argv[]) if (::GetConsoleWindow()) { ::ShowWindow(::GetConsoleWindow(), SW_SHOW); -} + } #ifndef NDEBUG SetUnhandledExceptionFilter(unhandled_handler); AddVectoredExceptionHandler(1, unhandled_handler); @@ -1210,7 +1210,7 @@ int main(int argc, char* argv[]) print_help(cli.command); return 1; } -} + } catch (fs::filesystem_error& ex) { std::cout << "std::filesystem fatal error." << std::endl << "what(): " << ex.what() << '\n'