Skip to content
This repository has been archived by the owner on Feb 16, 2024. It is now read-only.

Commit

Permalink
Begin reworking PIE loading and misc
Browse files Browse the repository at this point in the history
  • Loading branch information
maxsupermanhd committed Jan 7, 2022
1 parent f8fa8c0 commit 49bf8e6
Show file tree
Hide file tree
Showing 13 changed files with 510 additions and 240 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"cmake.configureOnOpen": true
"cmake.configureOnOpen": true,
"C_Cpp.errorSquiggles": "Disabled"
}
10 changes: 7 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
cmake_minimum_required(VERSION 3.9)
project(warzone_map_editor)

include("cmake/git.cmake")

project(warzone_map_editor VERSION ${GIT_TAG})

set(CMAKE_COLOR_MAKEFILE ON)
#set(CMAKE_VERBOSE_MAKEFILE ON)
Expand All @@ -13,12 +16,13 @@ add_subdirectory(lib/WMT)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=address")
set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fsanitize=address")


find_package(SDL2 REQUIRED)
find_package(SDL2_image REQUIRED)
set(OpenGL_GL_PREFERENCE LEGACY)
find_package(OpenGL REQUIRED)

configure_file(src/build.h.in src/build.h)

add_definitions(-DIMGUI_IMPL_OPENGL_LOADER_GLAD)
file(GLOB srcfiles "src/*.cpp" "src/*.c" "src/*.hpp" "src/*.h" "lib/imgui/*.cpp" "lib/imgui/*.h")
file(GLOB libfiles "lib/*.cpp" "lib/*.c" "lib/*.hpp" "lib/*.h")
Expand All @@ -27,7 +31,7 @@ file(GLOB gladfiles "lib/glad/src/glad.cpp" "lib/glad/include/glad.h")
add_executable(main ${libfiles} ${srcfiles} ${gladfiles})
set_property(TARGET main PROPERTY CXX_STANDARD 17)
link_directories("lib/" "lib/glad/src/")
include_directories("lib/glad/include/" "lib/imgui/" "lib/" ${GLFW3_INCLUDE_DIR} ${SDL2_INCLUDE_DIRS} ${SDL2_IMAGE_INCLUDE_DIRS} ${OPENGL_INCLUDE_DIR} ${GLEW_INCLUDE_DIRS})
include_directories(${CMAKE_CURRENT_BINARY_DIR} "lib/glad/include/" "lib/imgui/" "lib/" ${GLFW3_INCLUDE_DIR} ${SDL2_INCLUDE_DIRS} ${SDL2_IMAGE_INCLUDE_DIRS} ${OPENGL_INCLUDE_DIR} ${GLEW_INCLUDE_DIRS})
target_link_libraries(main libwmt GL GLU glfw GLEW ${GLFW3_LIBRARY} ${SDL2_LIBRARIES} ${SDL2_IMAGE_LIBRARIES} ${OPENGL_LIBRARIES} ${GLEW_LIBRARIES})

set(GLAD_DIR "lib/glad")
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@ Not many people work on map editor so it is pretty incomplete, here is what can

## License

GPL-2.0
GPL-2.0
32 changes: 32 additions & 0 deletions cmake/git.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
execute_process(COMMAND git log --pretty=format:'%h' -n 1
OUTPUT_VARIABLE GIT_REV
ERROR_QUIET)
if ("${GIT_REV}" STREQUAL "")
set(GIT_REV "N/A")
set(GIT_DIFF "")
set(GIT_TAG "0.0")
set(GIT_BRANCH "N/A")
message(WARNING "No git version detected!")
else()
execute_process(
COMMAND bash -c "git diff --quiet --exit-code || echo +"
OUTPUT_VARIABLE GIT_DIFF)
execute_process(
COMMAND git describe --tags
OUTPUT_VARIABLE GIT_TAG_RAW ERROR_QUIET)
execute_process(
COMMAND git rev-parse --abbrev-ref HEAD
OUTPUT_VARIABLE GIT_BRANCH)

string(STRIP "${GIT_REV}" GIT_REV)
string(SUBSTRING "${GIT_REV}" 1 7 GIT_REV)
string(STRIP "${GIT_DIFF}" GIT_DIFF)
string(STRIP "${GIT_TAG_RAW}" GIT_TAG_RAW)
string(STRIP "${GIT_BRANCH}" GIT_BRANCH)
string(REGEX MATCH "^[0-9]+\\.[0-9]+\\.[0-9]+" GIT_TAG "${GIT_TAG_RAW}")
if ("${GIT_TAG}" STREQUAL "")
set(GIT_TAG "0.0")
# message(WARNING "Git tag is empty, defaulting to 0.0")
endif()
message(STATUS "Git: ${GIT_REV} ${GIT_BRANCH} ${GIT_TAG}")
endif()
1 change: 0 additions & 1 deletion src/Object3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@

#include <string>
#include "glad/glad.h"
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
Expand Down
300 changes: 300 additions & 0 deletions src/Pie.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,300 @@
/*
This file is part of WZ2100 Map Editor.
Copyright (C) 2020-2021 maxsupermanhd
Copyright (C) 2020-2021 bjorn-ali-goransson
WZ2100 Map Editor is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
WZ2100 Map Editor is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with WZ2100 Map Editor; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include "Pie.h"
#include "log.hpp"
#include "other.h"
#include <stdlib.h>
#include <string.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <string>

PIElevel::~PIElevel() {
if(this->points) {
free(points);
}
if(this->normals) {
free(this->normals);
}
if(this->connectors) {
free(this->connectors);
}
if(this->anim) {
free(this->anim);
}
if(this->shadowpoints) {
free(this->shadowpoints);
}
if(this->shadowpolygons) {
free(this->shadowpolygons);
}
}

PIEmodel::~PIEmodel() {
if(this->levels) {
for(int i = 0; i < this->levelscount; i++) {
this->levels[i].~PIElevel();
}
}
}

class AutoFreeFileHandle {
public:
FILE* f = NULL;
AutoFreeFileHandle(FILE* f) : f(f) {}
~AutoFreeFileHandle() {
if(f) {
fclose(f);
}
}
AutoFreeFileHandle() = delete;
AutoFreeFileHandle(const AutoFreeFileHandle&) = delete;
AutoFreeFileHandle& operator=(const AutoFreeFileHandle&) = delete;
};

bool PIEmodel::ReadPIE(std::string path) {
AutoFreeFileHandle fh(fopen(path.c_str(), "r"));
FILE* f = fh.f; // this is dirty hack to not call fclose on every return
if(f == NULL) {
log_error("Error opening file [%s]: %s", strerror(errno));
return false;
}
log_info("Loading PIE [%s]", path.c_str());

int ret = fscanf(f, "PIE %d\nTYPE %d\n", &this->ver, &this->type);
if(ret != 2) {
log_error("Failed to parse first 2 lines of PIE, ret %d", ret);
return false;
}

int snum = 3;
int nowlevel = -1;
char* cstr = NULL;
size_t len = 0;
ssize_t read = 0;
while((read = getline(&cstr, &len, f)) != -1) {
if(cstr == NULL) {
log_fatal("Something really bad happened to getline... [%s]", strerror(errno));
return false;
}
std::string str = std::string(cstr);

free(cstr); // this will result in a bunch of reallocations but oh well
cstr = NULL; // however now I don't need to clean anything up on every
len = 0; // return so I guess it's a win for me...

if(!strncmpl(str, "INTERPOLATE")) {
int v;
int r = sscanf(str, "INTERPOLATE %d", &v);
if(r != 1) {
log_error("PIE READ [%s] INTERPOLATE line %d ret %d", path.c_str(), snum, r);
return false;
}
this->interpolate = v;
} else if(!strncmpl(str, "TEXTURE")) {
char* texname; // technically we must free that pointer
int r = sscanf(str, "TEXTURE %*d %ms %d %d", &texname, &this->tsizeh, &this->tsizew);
if(r != 3) { // but what happens if that pointer never actually allocated
log_error("PIE READ [%s] TEXTURE line %d ret %d", path.c_str(), snum, r);
// free(texname); double free?
return false;
}
this->texturename = std::string(texname);
free(texname);
} else if(!strncmpl(str, "NORMALMAP")) {
char* texname;
int r = sscanf(str, "NORMALMAP %*d %ms", &texname);
if(r != 1) {
log_error("PIE READ [%s] NORMALMAP line %d ret %d", path.c_str(), snum, r);
return false;
}
this->normalname = std::string(texname);
free(texname);
} else if(!strncmpl(str, "SPECULARMAP")) {
char* texname;
int r = sscanf(str, "SPECULARMAP %*d %ms", &texname);
if(r != 1) {
log_error("PIE READ [%s] SPECULARMAP line %d ret %d", path.c_str(), snum, r);
return false;
}
this->specularname = std::string(texname);
free(texname);
} else if(!strncmpl(str, "EVENT")) {
int t;
char* file;
int r = sscanf(str, "EVENT %d %ms", &t, &file);
if(r != 2) {
log_error("PIE READ [%s] EVENT line %d ret %d", path.c_str(), snum, r);
return false;
}
if(t < 0 || t > 3) {
log_error("Not supported PIE [%s] EVENT %d line %d ret %d", path.c_str(), t, snum, r);
} else {
this->events[t] = std::string(file);
}
free(file);
} else if(!strncmpl(str, "LEVELS ")) {
int r = sscanf(str, "LEVELS %d", &this->levelscount);
if(r != 1) {
log_error("PIE READ [%s] LEVELS line %d ret %d", path.c_str(), snum, r);
return false;
}
this->levels = (PIElevel*)malloc(sizeof(PIElevel)*this->levelscount);
if(this->levels == NULL) {
log_error("PIE READ [%s] LEVELS %d line %d ret %d", path.c_str(), this->levelscount, snum, r);
log_fatal("Failed to allocate levels!!! [%s]", strerror(errno));
return false;
}
} else if(!strncmpl(str, "LEVEL ")) {
int newlevel = -1;
int r = sscanf(str, "LEVEL %d", &nowlevel);
if(r != 1) {
log_error("PIE READ [%s] LEVEL line %d ret %d", path.c_str(), snum, r);
return false;
}
if(newlevel != -1 && newlevel <= this->levelscount && newlevel > 0) {
nowlevel = newlevel-1;
} else {
log_error("PIE READ [%s] LEVEL %d line %d outside level allocation", path.c_str(), newlevel, snum);
}
} else if(!strncmpl(str, "MATERIALS ")) {
} else if(!strncmpl(str, "SHADERS ")) {
} else if(!strncmpl(str, "POINTS ")) {
if(nowlevel < 0) {
log_error("PIE READ [%s] POINTS line %d level is outside of logical range (%d)", nowlevel);
return false;
}
int r = sscanf(str, "POINTS %d", &this->levels[nowlevel].pointscount);
if(r != 1) {
log_error("PIE READ [%s] POINTS line %d ret %d level %d", path.c_str(), snum, r, nowlevel);
return false;
}
this->levels[nowlevel].points = (glm::vec3*)malloc(sizeof(glm::vec3)*this->levels[nowlevel].pointscount);
if(this->levels[nowlevel].points == NULL) {
log_error("PIE READ [%s] POINTS line %d level %d malloc failed, no memory left?!", path.c_str(), snum, nowlevel);
return false;
}
char* pstr = NULL;
size_t plen = 0;
ssize_t pread;
for(int pointnum = 0; pointnum < this->levels[nowlevel].pointscount; pointnum++) {
pread = getline(&pstr, &plen, f);
if(pread != -1) {
log_error("PIE READ [%s] POINTS line %d level %d getline failed %d %s", path.c_str(), snum, nowlevel, errno, strerror(errno));
free(pstr);
return false;
}
int pr = sscanf(pstr, "\t%f %f %f", &this->levels[nowlevel].points[pointnum].x, &this->levels[nowlevel].points[pointnum].y, &this->levels[nowlevel].points[pointnum].z);
if(pr != 3) {
log_error("PIE READ [%s] POINTS line %d level %d sscanf failed %d", path.c_str(), snum, nowlevel, pr);
free(pstr);
return false;
}
snum++;
}
free(pstr);
} else if(!strncmpl(str, "NORMALS ")) {
if(nowlevel < 0) {
log_error("PIE READ [%s] NORMALS line %d level is outside of logical range (%d)", nowlevel);
return false;
}
int r = sscanf(str, "NORMALS %d", &this->levels[nowlevel].normalscount);
if(r != 1) {
log_error("PIE READ [%s] NORMALS line %d ret %d level %d", path.c_str(), snum, r, nowlevel);
return false;
}
this->levels[nowlevel].normals = (glm::vec3*)malloc(sizeof(glm::vec3)*this->levels[nowlevel].normalscount*3);
if(this->levels[nowlevel].normals == NULL) {
log_error("PIE READ [%s] NORMALS line %d ret %d level %d malloc failed, no memory left?!", path.c_str(), snum, r, nowlevel);
return false;
}
char* pstr = NULL;
size_t plen = 0;
ssize_t pread;
for(int normalnum = 0; normalnum < this->levels[nowlevel].normalscount; normalnum++) {
pread = getline(&pstr, &plen, f);
if(pread != -1) {
log_error("PIE READ [%s] NORMALS line %d level %d getline failed %d %s", path.c_str(), snum, nowlevel, errno, strerror(errno));
free(pstr);
return false;
}
int pr = sscanf(pstr, "\t%f %f %f %f %f %f %f %f %f",
&this->levels[nowlevel].normals[normalnum*3+0].x,
&this->levels[nowlevel].normals[normalnum*3+0].y,
&this->levels[nowlevel].normals[normalnum*3+0].z,
&this->levels[nowlevel].normals[normalnum*3+1].x,
&this->levels[nowlevel].normals[normalnum*3+1].y,
&this->levels[nowlevel].normals[normalnum*3+1].z,
&this->levels[nowlevel].normals[normalnum*3+2].x,
&this->levels[nowlevel].normals[normalnum*3+2].y,
&this->levels[nowlevel].normals[normalnum*3+2].z);
if(pr != 9) {
log_error("PIE READ [%s] NORMALS line %d level %d sscanf failed %d", path.c_str(), snum, nowlevel, pr);
free(pstr);
return false;
}
snum++;
}
free(pstr);
} else if(!strncmpl(str, "POLYGONS ")) {
if(nowlevel < 0) {
log_error("PIE READ [%s] POLYGONS line %d level is outside of logical range (%d)", nowlevel);
return false;
}
int r = sscanf(str, "POLYGONS %d", &this->levels[nowlevel].polygonscount);
if(r != 1) {
log_error("PIE READ [%s] POLYGONS line %d ret %d level %d", path.c_str(), snum, r, nowlevel);
return false;
}
this->levels[nowlevel].polygons = (PIEpolygon*)malloc(sizeof(PIEpolygon)*this->levels[nowlevel].polygonscount);
if(this->levels[nowlevel].polygons == NULL) {
log_error("PIE READ [%s] POLYGONS line %d ret %d level %d malloc failed, no memory left?!", path.c_str(), snum, r, nowlevel);
return false;
}
char* pstr = NULL;
size_t plen = 0;
ssize_t pread;
for(int polygonnum = 0; polygonnum < this->levels[nowlevel].polygonscount; polygonnum++) {
pread = getline(&pstr, &plen, f);
if(pread != -1) {
log_error("PIE READ [%s] POLYGONS line %d level %d getline failed %d %s", path.c_str(), snum, nowlevel, errno, strerror(errno));
free(pstr);
return false;
}
int pr = sscanf(pstr, "\t%d %d", &this->levels[nowlevel].polygons[polygonnum].flags, &this->levels[nowlevel].polygons[polygonnum].pcount);
if(pr != 2) {
log_error("PIE READ [%s] POLYGONS line %d level %d sscanf failed %d", path.c_str(), snum, nowlevel, pr);
free(pstr);
return false;
}
if(!(this->levels[nowlevel].polygons[polygonnum].flags & 0x00000200)) {
log_error("PIE READ [%s] POLYGONS line %d level %d flag is not 200 %d", path.c_str(), snum, nowlevel, this->levels[nowlevel].polygons[polygonnum].flags);
free(pstr);
return false;
}
snum++;
}
free(pstr);
}
snum++;
}
return true;
}
Loading

0 comments on commit 49bf8e6

Please sign in to comment.