Skip to content

Commit 92e1899

Browse files
authored
Merge pull request #5 from bgadoury-git/Windows_P&P_Compatibility
Visual Studio Errors
2 parents 4e7f4df + 4b6e0c8 commit 92e1899

3 files changed

Lines changed: 249 additions & 138 deletions

File tree

src/Processing.cpp

Lines changed: 93 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
11
#if __has_include("stb_truetype.h")
22
# define PROCESSING_HAS_STB_TRUETYPE 1
33
# define STB_TRUETYPE_IMPLEMENTATION
4+
# if defined(_MSC_VER)
5+
# pragma warning(push)
6+
# pragma warning(disable: 4365)
7+
# endif
48
# include "stb_truetype.h"
9+
# if defined(_MSC_VER)
10+
# pragma warning(pop)
11+
# endif
512
#else
613
# define PROCESSING_HAS_STB_TRUETYPE 0
714
#endif
815

916
#include "Processing.h"
17+
#ifdef _MSC_VER
18+
#pragma warning(push)
19+
#pragma warning(disable: 4365 4245 4100 4189)
20+
#endif
1021
#ifdef __EMSCRIPTEN__
1122
#include <emscripten.h>
1223
#include <emscripten/html5.h>
@@ -16,6 +27,7 @@
1627
#undef GL_QUAD_STRIP
1728
#define GL_QUAD_STRIP GL_TRIANGLE_STRIP
1829
#endif
30+
1931
#include <csignal>
2032
#include <cstdlib>
2133
#include <cmath>
@@ -30,9 +42,11 @@
3042
#include <objc/message.h>
3143
#include <dlfcn.h>
3244
#endif
45+
3346
#ifndef _WIN32
3447
#include <thread>
3548
#endif
49+
3650
#include <vector>
3751
#include <array>
3852
#include <string>
@@ -52,13 +66,26 @@
5266
// Uncomment + drop stb_image_write.h to enable saveFrame()/save():
5367
// #define STB_IMAGE_WRITE_IMPLEMENTATION
5468
#define STB_IMAGE_WRITE_IMPLEMENTATION
69+
#if defined(__clang__)
5570
#pragma clang diagnostic push
5671
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
72+
#elif defined(__GNUC__)
5773
#pragma GCC diagnostic push
5874
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
75+
#endif
76+
#ifdef _MSC_VER
77+
#pragma warning(push)
78+
#pragma warning(disable: 4365)
79+
#endif
5980
#include "stb_image_write.h"
81+
#ifdef _MSC_VER
82+
#pragma warning(pop)
83+
#endif
84+
#if defined(__clang__)
6085
#pragma clang diagnostic pop
86+
#elif defined(__GNUC__)
6187
#pragma GCC diagnostic pop
88+
#endif
6289

6390
// ── Manual glu replacements (no GLU header needed) ───────────────────────────
6491
static void _gluPerspective(double fovY_deg, double aspect, double zNear, double zFar) {
@@ -161,6 +188,31 @@ std::function<void()> _onWindowMoved;
161188

162189
namespace Processing {
163190

191+
static FILE* processingOpenFile(const char* path, const char* mode) {
192+
#ifdef _WIN32
193+
FILE* file = nullptr;
194+
return ::fopen_s(&file, path, mode) == 0 ? file : nullptr;
195+
#else
196+
return ::fopen(path, mode);
197+
#endif
198+
}
199+
200+
static FILE* processingOpenPipe(const char* command, const char* mode) {
201+
#ifdef _WIN32
202+
return ::_popen(command, mode);
203+
#else
204+
return ::popen(command, mode);
205+
#endif
206+
}
207+
208+
static int processingClosePipe(FILE* pipe) {
209+
#ifdef _WIN32
210+
return ::_pclose(pipe);
211+
#else
212+
return ::pclose(pipe);
213+
#endif
214+
}
215+
164216
static void _doEnableDebugConsole() {
165217
#ifdef _WIN32
166218
if (AllocConsole()) {
@@ -312,8 +364,8 @@ color PApplet::makeColor(float gray,float alpha){
312364
float br=gray/colorMaxB;
313365
br=::std::fmax(0.f,::std::fmin(1.f,br));
314366
int v=(int)(br*255);
315-
unsigned int a=::std::fmax(0.f,::std::fmin(1.f,alpha/colorMaxA))*255;
316-
return colorVal(v,v,v,(int)a);
367+
unsigned int a=static_cast<unsigned int>(::std::fmax(0.f,::std::fmin(1.f,alpha/colorMaxA))*255.0f);
368+
return colorVal(v,v,v,static_cast<int>(a));
317369
}
318370
return makeColor(gray,gray,gray,alpha);
319371
}
@@ -2271,7 +2323,7 @@ void PApplet::drawBitmapStr(float x, float y, const ::std::string& s, int scale)
22712323
}
22722324

22732325
float PApplet::bitmapStrWidth(const ::std::string& s, int scale) {
2274-
return s.size() * (BF_GW+1) * scale;
2326+
return static_cast<float>(s.size()) * static_cast<float>(BF_GW+1) * static_cast<float>(scale);
22752327
}
22762328

22772329
// -- TTF rendering -------------------------------------------------------------
@@ -2376,7 +2428,7 @@ void PApplet::renderText(const ::std::string& msg, float x, float y) {
23762428
// Bitmap fallback
23772429
int sc = ::std::max(1,(int)(g_textSize/8.0f));
23782430
// Shift so baseline sits at y (bitmap font: ascent = BF_GH-2 rows)
2379-
float ascent = (BF_GH - 2) * sc;
2431+
float ascent = static_cast<float>(BF_GH - 2) * static_cast<float>(sc);
23802432
drawBitmapStr(dx, dy - ascent, ls[li], sc);
23812433
}
23822434
}
@@ -2515,7 +2567,7 @@ float PApplet::textAscent() {
25152567
}
25162568
#endif
25172569
int sc = ::std::max(1,(int)(g_textSize/8.0f));
2518-
return (BF_GH - 2) * sc;
2570+
return static_cast<float>(BF_GH - 2) * static_cast<float>(sc);
25192571
}
25202572

25212573
float PApplet::textDescent() {
@@ -2550,7 +2602,9 @@ PImage* PApplet::loadImage(const ::std::string& path){
25502602
// Handle URLs: download with curl/wget and validate image magic bytes
25512603
if (path.size()>7 && (path.substr(0,7)=="http://" || path.substr(0,8)=="https://")){
25522604
#ifdef _WIN32
2553-
::std::string tmp=::std::string(getenv("TEMP")?getenv("TEMP"):"C:\\Temp")+"\\pg_img_";
2605+
::std::string tempDir = processingEnvironmentVariable("TEMP");
2606+
if (tempDir.empty()) tempDir = "C:\\Temp";
2607+
::std::string tmp=tempDir+"\\pg_img_";
25542608
#else
25552609
::std::string tmp="/tmp/pg_img_";
25562610
#endif
@@ -2561,7 +2615,7 @@ PImage* PApplet::loadImage(const ::std::string& path){
25612615
for(char& c:bn) if(c==':'||c=='*'||c=='<'||c=='>'||c=='|') c='_';
25622616
tmp+=bn;
25632617
auto isValidImg=[&]()->bool{
2564-
FILE* f2=fopen(tmp.c_str(),"rb"); if(!f2) return false;
2618+
FILE* f2=processingOpenFile(tmp.c_str(),"rb"); if(!f2) return false;
25652619
fseek(f2,0,SEEK_END); long sz=ftell(f2); fseek(f2,0,SEEK_SET);
25662620
unsigned char h[4]={}; fread(h,1,4,f2); fclose(f2);
25672621
if(sz<100) return false;
@@ -2594,9 +2648,8 @@ PImage* PApplet::loadImage(const ::std::string& path){
25942648
}
25952649
// Search paths: current dir, data/, files/, and sketch subdirs
25962650
// Check PROCESSING_SKETCH_PATH env var set by IDE
2597-
::std::string _sketchDir;
2598-
if (const char* _sp = ::std::getenv("PROCESSING_SKETCH_PATH"))
2599-
_sketchDir = ::std::string(_sp) + "/";
2651+
::std::string _sketchDir = processingEnvironmentVariable("PROCESSING_SKETCH_PATH");
2652+
if (!_sketchDir.empty()) _sketchDir += "/";
26002653
// Also get the directory of the running executable
26012654
::std::string _exeDir;
26022655
{
@@ -2834,13 +2887,13 @@ void PApplet::filter(int mode, float param) {
28342887
int r=buf[i*4],g=buf[i*4+1],b=buf[i*4+2];
28352888
int grey=(r+g+b)/3;
28362889
if (mode==GRAY) { buf[i*4]=buf[i*4+1]=buf[i*4+2]=(unsigned char)grey; }
2837-
else if (mode==INVERT) { buf[i*4]=255-r; buf[i*4+1]=255-g; buf[i*4+2]=255-b; }
2890+
else if (mode==INVERT) { buf[i*4]=static_cast<unsigned char>(255-r); buf[i*4+1]=static_cast<unsigned char>(255-g); buf[i*4+2]=static_cast<unsigned char>(255-b); }
28382891
else if (mode==THRESHOLD) { unsigned char t=(grey>param*255)?255:0; buf[i*4]=buf[i*4+1]=buf[i*4+2]=t; }
2839-
else if (mode==OPAQUE) { buf[i*4+3]=255; }
2892+
else if (mode==OPAQUE) { buf[i*4+3]=static_cast<unsigned char>(255); }
28402893
else if (mode==POSTERIZE) {
28412894
int levels = ::std::max(2,(int)param);
28422895
auto post = [levels](int v){ return (int)((int)(v*(levels-1)/255.0f+0.5f)*255/(levels-1)); };
2843-
buf[i*4]=post(r); buf[i*4+1]=post(g); buf[i*4+2]=post(b);
2896+
buf[static_cast<size_t>(i)*4u]=static_cast<unsigned char>(post(r)); buf[static_cast<size_t>(i)*4u+1u]=static_cast<unsigned char>(post(g)); buf[static_cast<size_t>(i)*4u+2u]=static_cast<unsigned char>(post(b));
28442897
}
28452898
}
28462899
} else if (mode == BLUR) {
@@ -2855,7 +2908,7 @@ void PApplet::filter(int mode, float param) {
28552908
sr+=tmp[j]; sg+=tmp[j+1]; sb+=tmp[j+2]; sa+=tmp[j+3]; cnt++;
28562909
}
28572910
int i=(y*w+x2)*4;
2858-
buf[i]=sr/cnt; buf[i+1]=sg/cnt; buf[i+2]=sb/cnt; buf[i+3]=sa/cnt;
2911+
buf[i]=static_cast<unsigned char>(sr/cnt); buf[i+1]=static_cast<unsigned char>(sg/cnt); buf[i+2]=static_cast<unsigned char>(sb/cnt); buf[i+3]=static_cast<unsigned char>(sa/cnt);
28592912
}
28602913
} else if (mode == ERODE || mode == DILATE) {
28612914
::std::vector<unsigned char> tmp(buf);
@@ -3050,7 +3103,7 @@ void PApplet::saveFrame(const ::std::string& filename) {
30503103
for (int x = 0; x < w * 3; x++)
30513104
::std::swap(px[y*w*3+x], px[(h-1-y)*w*3+x]);
30523105
::std::string ext = fn.size() > 4 ? fn.substr(fn.size()-4) : "";
3053-
for (auto& c : ext) c = tolower(c);
3106+
for (auto& c : ext) c = static_cast<char>(tolower(static_cast<unsigned char>(c)));
30543107
int ok = 0;
30553108
if (ext == ".png") ok = stbi_write_png(fn.c_str(), w, h, 3, px.data(), w*3);
30563109
else if (ext == ".jpg" || ext == "jpeg") ok = stbi_write_jpg(fn.c_str(), w, h, 3, px.data(), 95);
@@ -3622,22 +3675,22 @@ void PApplet::run(){
36223675
{
36233676
::std::string _homeDir;
36243677
#ifdef _WIN32
3625-
if (const char* h = ::std::getenv("USERPROFILE")) _homeDir = h;
3678+
_homeDir = processingEnvironmentVariable("USERPROFILE");
36263679
#else
3627-
if (const char* h = ::std::getenv("HOME")) _homeDir = h;
3680+
_homeDir = processingEnvironmentVariable("HOME");
36283681
#endif
36293682
::std::string _modePath;
3630-
if (const char* mp = ::std::getenv("PROCESSING_MODE_PATH"))
3631-
_modePath = ::std::string(mp) + "/";
3683+
_modePath = processingEnvironmentVariable("PROCESSING_MODE_PATH");
3684+
if (!_modePath.empty()) _modePath += "/";
36323685

36333686
// Font name used by Processing4
36343687
const ::std::string _font = "ProcessingSansPro-Regular.ttf";
36353688

36363689
// Check Documents/Processing on Windows (user sketchbook)
36373690
::std::string _docsPath;
36383691
#ifdef _WIN32
3639-
if (const char* ud = ::std::getenv("USERPROFILE"))
3640-
_docsPath = ::std::string(ud) + "/Documents/Processing/";
3692+
::std::string userProfile = processingEnvironmentVariable("USERPROFILE");
3693+
if (!userProfile.empty()) _docsPath = userProfile + "/Documents/Processing/";
36413694
#endif
36423695

36433696
if (!tryLoadTTF("fonts/" + _font, g_textSize) &&
@@ -4479,7 +4532,7 @@ static PShape* svgLoad(const ::std::string& path){
44794532
// Search paths
44804533
::std::vector<::std::string> tries={path,"data/"+path,"files/"+path};
44814534
::std::string found;
4482-
for(auto& t:tries){FILE* f=fopen(t.c_str(),"r");if(f){fclose(f);found=t;break;}}
4535+
for(auto& t:tries){FILE* f=processingOpenFile(t.c_str(),"r");if(f){fclose(f);found=t;break;}}
44834536
if(found.empty()){::std::cerr<<"loadShape: file not found: "<<path<<"\n";return new PShape();}
44844537

44854538
::std::ifstream f(found);
@@ -4681,7 +4734,7 @@ static ::std::unordered_map<::std::string,GLuint> objLoadMtl(const ::std::string
46814734
static PShape* objLoad(const ::std::string& path){
46824735
::std::vector<::std::string> tries={path,"data/"+path,"files/"+path};
46834736
::std::string found;
4684-
for(auto& t:tries){FILE* f2=fopen(t.c_str(),"r");if(f2){fclose(f2);found=t;break;}}
4737+
for(auto& t:tries){FILE* f2=processingOpenFile(t.c_str(),"r");if(f2){fclose(f2);found=t;break;}}
46854738
if(found.empty()){::std::cerr<<"loadShape: OBJ not found: "<<path<<"\n";return new PShape();}
46864739

46874740
// Get directory for relative texture paths
@@ -5007,7 +5060,7 @@ PFont* PApplet::createFont(const ::std::string& name, float size, bool /*smooth*
50075060
// Also search system font dirs recursively (Linux: fc-list output)
50085061
#ifndef _WIN32
50095062
{
5010-
FILE* fc = popen(("fc-list : file | grep -i '" + nameNoExt + "' | head -5").c_str(), "r");
5063+
FILE* fc = processingOpenPipe(("fc-list : file | grep -i '" + nameNoExt + "' | head -5").c_str(), "r");
50115064
if (fc) {
50125065
char buf[512];
50135066
while (fgets(buf, sizeof(buf), fc)) {
@@ -5022,7 +5075,7 @@ PFont* PApplet::createFont(const ::std::string& name, float size, bool /*smooth*
50225075
if (!fpath.empty()) paths.push_back(fpath);
50235076
}
50245077
}
5025-
pclose(fc);
5078+
processingClosePipe(fc);
50265079
}
50275080
}
50285081
#endif
@@ -5078,26 +5131,26 @@ ::std::string PApplet::selectInput(const ::std::string& prompt,const ::std::stri
50785131
(void)prompt; return "";
50795132
#endif
50805133
::std::string cmd="zenity --file-selection --title=\""+prompt+"\" 2>/dev/null";
5081-
FILE* p=popen(cmd.c_str(),"r"); if(!p)return "";
5082-
char buf[4096]=""; fgets(buf,sizeof(buf),p); pclose(p);
5134+
FILE* p=processingOpenPipe(cmd.c_str(),"r"); if(!p)return "";
5135+
char buf[4096]=""; fgets(buf,sizeof(buf),p); processingClosePipe(p);
50835136
::std::string r(buf); if(!r.empty()&&r.back()=='\n')r.pop_back(); return r;
50845137
}
50855138
::std::string PApplet::selectOutput(const ::std::string& prompt,const ::std::string&){
50865139
#ifdef __EMSCRIPTEN__
50875140
(void)prompt; return "";
50885141
#endif
50895142
::std::string cmd="zenity --file-selection --save --title=\""+prompt+"\" 2>/dev/null";
5090-
FILE* p=popen(cmd.c_str(),"r"); if(!p)return "";
5091-
char buf[4096]=""; fgets(buf,sizeof(buf),p); pclose(p);
5143+
FILE* p=processingOpenPipe(cmd.c_str(),"r"); if(!p)return "";
5144+
char buf[4096]=""; fgets(buf,sizeof(buf),p); processingClosePipe(p);
50925145
::std::string r(buf); if(!r.empty()&&r.back()=='\n')r.pop_back(); return r;
50935146
}
50945147
::std::string PApplet::selectFolder(const ::std::string& prompt){
50955148
#ifdef __EMSCRIPTEN__
50965149
(void)prompt; return "";
50975150
#endif
50985151
::std::string cmd="zenity --file-selection --directory --title=\""+prompt+"\" 2>/dev/null";
5099-
FILE* p=popen(cmd.c_str(),"r"); if(!p)return "";
5100-
char buf[4096]=""; fgets(buf,sizeof(buf),p); pclose(p);
5152+
FILE* p=processingOpenPipe(cmd.c_str(),"r"); if(!p)return "";
5153+
char buf[4096]=""; fgets(buf,sizeof(buf),p); processingClosePipe(p);
51015154
::std::string r(buf); if(!r.empty()&&r.back()=='\n')r.pop_back(); return r;
51025155
}
51035156

@@ -5111,9 +5164,8 @@ PImage* PApplet::requestImage(const ::std::string& path){
51115164
::std::thread([img, path]{
51125165
// Resolve search paths same as loadImage
51135166
// Check PROCESSING_SKETCH_PATH env var set by IDE
5114-
::std::string _sketchDir;
5115-
if (const char* _sp = ::std::getenv("PROCESSING_SKETCH_PATH"))
5116-
_sketchDir = ::std::string(_sp) + "/";
5167+
::std::string _sketchDir = processingEnvironmentVariable("PROCESSING_SKETCH_PATH");
5168+
if (!_sketchDir.empty()) _sketchDir += "/";
51175169
// Also get the directory of the running executable
51185170
::std::string _exeDir;
51195171
{
@@ -5139,7 +5191,7 @@ PImage* PApplet::requestImage(const ::std::string& path){
51395191
};
51405192
::std::string found;
51415193
for (auto& t : tries) {
5142-
FILE* f = fopen(t.c_str(), "rb");
5194+
FILE* f = processingOpenFile(t.c_str(), "rb");
51435195
if (f) { fclose(f); found = t; break; }
51445196
}
51455197
if (found.empty()) {
@@ -5248,8 +5300,8 @@ PImage getRegion(int x,int y,int w,int h){
52485300

52495301
::std::vector<::std::string> PApplet::loadStrings(const ::std::string& path) {
52505302
::std::vector<::std::string> lines;
5251-
::std::string sketchDir;
5252-
if (const char* sp = ::std::getenv("PROCESSING_SKETCH_PATH")) sketchDir = ::std::string(sp) + "/";
5303+
::std::string sketchDir = processingEnvironmentVariable("PROCESSING_SKETCH_PATH");
5304+
if (!sketchDir.empty()) sketchDir += "/";
52535305
::std::ifstream f(path);
52545306
if (!f) f.open(sketchDir + path);
52555307
if (!f) f.open(sketchDir + "data/" + path);
@@ -5321,3 +5373,7 @@ ::std::string PApplet::binary(int v) {
53215373

53225374
} // namespace Processing
53235375

5376+
#ifdef _MSC_VER
5377+
#pragma warning(pop)
5378+
#endif
5379+

0 commit comments

Comments
 (0)