From 25548aa3a2c3fd86202b01a88df6abd820a9eb6d Mon Sep 17 00:00:00 2001 From: Sam Moore Date: Sun, 5 Oct 2014 00:31:08 +0800 Subject: [PATCH] Add MinGW Win32 Cross Compiling Not tested with Qt4 yet, but works with QUADTREE_DISABLED Build procedure: 1. Put source for GMP and SDL2 in ipdf/code/contrib/ Do 2. and 3. for both 2. Run `./configure --host=i686-w64-mingw32 --prefix="ipdf/code/contrib/win32"` 3. `make; make install` 4. In ipdf/code/src, run `make ARCH=win32 CONTROLPANEL=disabled` 5. Download SDL2.dll for the binary Will try and get Qt4 support in the morning I guess. I am doing this because I want it to be easy for marker(s) to run the software. So I will make a precompiled ipdf.exe for windows in addition to the linux binary. Tested under wine, seems to work. ALSO Why the hell is there a goto in document.cpp --- .gitignore | 1 + src/Makefile | 17 ++++++++++++++--- src/debugscript.cpp | 4 +++- src/document.cpp | 2 +- src/gmprat.h | 2 +- src/log.cpp | 6 ++++++ src/main.cpp | 3 +++ src/main.h | 19 ++++++++++++++++--- src/objectrenderer.cpp | 2 +- src/paranoidnumber.h | 8 ++++++-- src/path.h | 5 ++--- src/screen.cpp | 5 ++++- src/view.h | 4 ++-- 13 files changed, 60 insertions(+), 18 deletions(-) diff --git a/.gitignore b/.gitignore index 7f6e4df..025bbce 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ tools/* !tools/*.py !src/tests/*.cpp !src/tests/*.h +src/*.dll diff --git a/src/Makefile b/src/Makefile index 23930b6..c64bebd 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,9 +1,16 @@ #Makefile ARCH := $(shell uname -m) # TODO: stb_truetype doesn't compile with some of these warnings. -CXX = g++ -std=c++0x -g -Wall -Werror -Wshadow -pedantic -rdynamic + +# This seemed like a good idea 2 hours ago ok... +ifeq ($(ARCH), win32) + CXX = i686-w64-mingw32-g++ -std=c++11 -g -Wall -Werror -Wshadow -pedantic +else + CXX = g++ -std=c++11 -g -Wall -Werror -Wshadow -pedantic -rdynamic +endif + MAIN = main.o -OBJ = log.o real.o bezier.o objectrenderer.o view.o screen.o graphicsbuffer.o framebuffer.o shaderprogram.o stb_truetype.o gl_core44.o path.o document.o debugscript.o +OBJ = log.o real.o bezier.o objectrenderer.o view.o screen.o graphicsbuffer.o framebuffer.o shaderprogram.o stb_truetype.o gl_core44.o path.o document.o debugscript.o paranoidnumber.o QT_INCLUDE := -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -Itests -I. QT_DEF := -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB @@ -12,10 +19,12 @@ QT_LIB := -L/usr/lib/x86_64-linux-gnu -lQtGui -lQtCore -lpthread LIB_x86_64 = ../contrib/lib/libSDL2-2.0.so.0 -lGL -lgmp LIB_i386 = ../contrib/lib32/libSDL2-2.0.so.0 -lGL -lgmp LIB_i686 = $(LIB_i386) +LIB_win32 = -mwindows -lmingw32 -L../contrib/win32/lib/ -lSDL2main -lSDL2 -lgmp -static-libgcc -static-libstdc++ MAINRPATH_x86_64 = -Wl,-rpath,'$$ORIGIN/../contrib/lib' MAINRPATH_i386 = -Wl,-rpath,'$$ORIGIN/../contrib/lib32' MAINRPATH_i686 = $(MAINRPATH_i386) +MAINRPATH_win32 = -Wl,-rpath,'$$ORIGIN/../contrib/win32/lib' TESTRPATH_x86_64 = -Wl,-rpath,'$$ORIGIN/../../contrib/lib' TESTRPATH_i386 = -Wl,-rpath,'$$ORIGIN/../../contrib/lib32' TESTRPATH_i686 = $(TESTRPATH_i386) @@ -24,11 +33,13 @@ DEPS := $(OBJPATHS:%.o=%.d) CFLAGS_x86_64 := -I../contrib/include/SDL2 -I`pwd` CFLAGS_i386 := -I../contrib/include32/SDL2 -I`pwd` CFLAGS_i686 := $(CFLAGS_i386) +CFLAGS_win32 := -I../contrib/win32/include/SDL2 -I`pwd` -I../contrib/win32/include LIB := $(LIB_$(ARCH)) MAINRPATH := $(MAINRPATH_$(ARCH)) TESTRPATH := $(TESTRPATH_$(ARCH)) + CFLAGS := $(CFLAGS_$(ARCH)) RM = rm -f @@ -76,7 +87,7 @@ ifeq ($(REALTYPE),7) endif ifeq ($(REALTYPE),8) - OBJ := $(OBJ) paranoidnumber.o + OBJ := $(OBJ) endif ifeq ($(REALTYPE),9) diff --git a/src/debugscript.cpp b/src/debugscript.cpp index c2cc2ef..9fd95a6 100644 --- a/src/debugscript.cpp +++ b/src/debugscript.cpp @@ -240,12 +240,14 @@ void DebugScript::PrintPerformance(View * view, Screen * scr) now.view_bounds = view->GetBounds(); // object_count clock delta_clock x Log10(x) y Log10(y) w Log10(w) Size(w) - printf("%d\t%lu\t%lu\t%s\t%f\t%s\t%f\t%s\t%f\t%lu\n", + #ifdef QUADTREE_DISABLED + printf("%d\t%llu\t%llu\t%s\t%f\t%s\t%f\t%s\t%f\t%u\n", now.object_count, (uint64_t)now.clock, (uint64_t)(now.clock - m_perf_last.clock), Str(now.view_bounds.x).c_str(), Log10(Abs(now.view_bounds.x)), Str(now.view_bounds.y).c_str(), Log10(Abs(now.view_bounds.y)), Str(now.view_bounds.w).c_str(), Log10(now.view_bounds.w), Size(now.view_bounds.w)); + #endif m_perf_last = now; } diff --git a/src/document.cpp b/src/document.cpp index 7dda475..22e4235 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -355,8 +355,8 @@ unsigned Document::Add(ObjectType type, const Rect & bounds, unsigned data_index m_quadtree.nodes[overlay].object_end = m_count+1; m_quadtree.nodes[qti].next_overlay = overlay; } +done: // matches is not amused #endif -done: return (m_count++); // Why can't we just use the size of types or something? } diff --git a/src/gmprat.h b/src/gmprat.h index c19d95d..b92d5af 100644 --- a/src/gmprat.h +++ b/src/gmprat.h @@ -33,7 +33,7 @@ class Gmprat return "-" + operator-().Str(); } double p = Log10(); - if (isinf(p)) + if (std::isinf(p)) return "0"; int P = (int)p; diff --git a/src/log.cpp b/src/log.cpp index 49b209a..a695b0e 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -10,7 +10,9 @@ #include #include #include +#ifndef __MINGW32__ #include +#endif #ifdef LOG_SYSLOG @@ -145,8 +147,12 @@ void FatalEx(const char * funct, const char * file, int line, ...) */ void Backtrace(int size) { + #ifndef __MINGW32__ void * buffer[100]; int actual_size = backtrace(buffer, size); backtrace_symbols_fd(buffer, actual_size, fileno(stderr)); + #else + Error("Backtrace not supported by compiler"); + #endif } diff --git a/src/main.cpp b/src/main.cpp index a4c570b..051f7ce 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -31,7 +31,10 @@ int main(int argc, char ** argv) #endif // We want to crash if we ever get a NaN. + // AH, so *this* is where that got enabled, I was looking for compiler flags + #ifndef __MINGW32__ feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW); + #endif DebugRealInfo(); diff --git a/src/main.h b/src/main.h index 1f057ea..af7df43 100644 --- a/src/main.h +++ b/src/main.h @@ -90,11 +90,17 @@ void MainLoop(Document & doc, Screen & scr, View & view, int max_frames = -1) double total_cpu_time = 0; double total_gpu_time = 0; double total_real_time = 0; + + // MINGW doesn't support a lot of ctime stuff here + #ifndef __MINGW32__ struct timespec real_clock_start; struct timespec real_clock_now; struct timespec real_clock_prev; clock_gettime(CLOCK_MONOTONIC_RAW, &real_clock_start); real_clock_now = real_clock_start; + #endif + + double frames = 0; double data_rate = 0; // period between data output to stdout (if <= 0 there will be no output) uint64_t data_points = 0; @@ -102,7 +108,9 @@ void MainLoop(Document & doc, Screen & scr, View & view, int max_frames = -1) int frame_number = 0; while (scr.PumpEvents() && (max_frames < 0 || frame_number++ < max_frames)) { + #ifndef __MINGW32__ real_clock_prev = real_clock_now; + #endif ++frames; scr.Clear(); //view.ForceBoundsDirty(); @@ -119,11 +127,16 @@ void MainLoop(Document & doc, Screen & scr, View & view, int max_frames = -1) double cpu_frame = scr.GetLastFrameTimeCPU(); double gpu_frame = scr.GetLastFrameTimeGPU(); + total_cpu_time += cpu_frame; total_gpu_time += gpu_frame; + + #ifndef __MINGW32__ clock_gettime(CLOCK_MONOTONIC_RAW, &real_clock_now); double real_frame = (real_clock_now.tv_sec - real_clock_prev.tv_sec) + 1e-9*(real_clock_now.tv_nsec - real_clock_prev.tv_nsec); - - - total_real_time += real_frame; total_cpu_time += cpu_frame; total_gpu_time += gpu_frame; + #else + double real_frame = cpu_frame; + #endif + + total_real_time += real_frame; if (data_rate > 0 && total_real_time > data_rate*(data_points+1)) { printf("%lu\t%f\t%f\t%f\t%f\t%f\t%f\n", (long unsigned int)frames, total_real_time, total_cpu_time, total_gpu_time, real_frame, cpu_frame, gpu_frame); diff --git a/src/objectrenderer.cpp b/src/objectrenderer.cpp index 21c9648..886871c 100644 --- a/src/objectrenderer.cpp +++ b/src/objectrenderer.cpp @@ -243,7 +243,7 @@ void BezierRenderer::RenderBezierOnCPU(const Bezier & relative, const Rect & bou ObjectRenderer::RenderLineOnCPU(pix_bounds.x+pix_bounds.w, pix_bounds.y, pix_bounds.x+pix_bounds.w, pix_bounds.y+pix_bounds.h, target, Colour(0,255,0,0)); } - int64_t blen = min(50L,pix_bounds.w);//min(max(2U, (unsigned)Int64(Real(target.w)/view.GetBounds().w)), + int64_t blen = min((int64_t)50,pix_bounds.w);//min(max(2U, (unsigned)Int64(Real(target.w)/view.GetBounds().w)), //min((unsigned)(pix_bounds.w+pix_bounds.h)/4 + 1, 100U)); // DeCasteljau Divide the Bezier diff --git a/src/paranoidnumber.h b/src/paranoidnumber.h index a175ed5..29e15d5 100644 --- a/src/paranoidnumber.h +++ b/src/paranoidnumber.h @@ -12,14 +12,14 @@ #include // it's going to be ok #include -#define PARANOID_DIGIT_T float // we could theoretically replace this with a template +#define PARANOID_DIGIT_T double // we could theoretically replace this with a template // but let's not do that... //#define PARANOID_CACHE_RESULTS //#define PARANOID_USE_ARENA -//#define PARANOID_SIZE_LIMIT 3 +#define PARANOID_SIZE_LIMIT 4 // Define to compare all ops against double ops and check within epsilon @@ -145,6 +145,8 @@ namespace IPDF // Like this one. It isn't const. double ToDouble() const {return (double)Digit();} + operator double() const {return ToDouble();} + // This one is probably const. bool Floating() const { @@ -332,6 +334,8 @@ T ParanoidNumber::Convert() const + + } #endif //_PARANOIDNUMBER_H diff --git a/src/path.h b/src/path.h index 85213c5..fffbeba 100644 --- a/src/path.h +++ b/src/path.h @@ -9,15 +9,14 @@ #ifdef TRANSFORM_BEZIERS_TO_PATH #include "gmprat.h" - + #include "paranoidnumber.h" #endif namespace IPDF { #ifdef TRANSFORM_BEZIERS_TO_PATH - #pragma message "Path using Gmprat for bounds" - typedef Gmprat PReal; + typedef ParanoidNumber PReal; #else typedef Real PReal; #endif diff --git a/src/screen.cpp b/src/screen.cpp index 46a2b73..0df64a2 100644 --- a/src/screen.cpp +++ b/src/screen.cpp @@ -14,6 +14,7 @@ using namespace IPDF; using namespace std; +#ifndef __MINGW32__ static void opengl_debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* msg, const void *data) { // Don't print out gl Errors we generated. @@ -22,7 +23,7 @@ static void opengl_debug_callback(GLenum source, GLenum type, GLuint id, GLenum // Spams this message on fglrx, disabling for now because it's damn annoying. // ERROR: opengl_debug_callback (screen.cpp:21) - OpenGL Error (1011): glObjectLabel failed because (depending on the operation) a referenced binding point is empty; a referenced name is not the name of an object; or the given name is otherwise not valid to this operation (GL_INVALID_VALUE) } - +#endif Screen::Screen(bool visible) { @@ -72,7 +73,9 @@ Screen::Screen(bool visible) glGenQueries(1, &m_frame_gpu_timer); glBeginQuery(GL_TIME_ELAPSED, m_frame_gpu_timer); + #ifndef __MINGW32__ glDebugMessageCallback(opengl_debug_callback, 0); + #endif GLuint default_vao; glGenVertexArrays(1, &default_vao); diff --git a/src/view.h b/src/view.h index cd94420..0359565 100644 --- a/src/view.h +++ b/src/view.h @@ -14,13 +14,13 @@ #ifdef TRANSFORM_BEZIERS_TO_PATH #include "gmprat.h" +#include "paranoidnumber.h" #endif namespace IPDF { #ifdef TRANSFORM_BEZIERS_TO_PATH - #pragma message "View using Gmprat for bounds" - typedef Gmprat VReal; + typedef ParanoidNumber VReal; #else typedef Real VReal; #endif -- 2.20.1