From b2d7bcc8b2f58d44cb3dbfe00d587f6756619f5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Madar=C3=A1sz?= Date: Tue, 10 Oct 2023 10:52:29 +0200 Subject: [PATCH] sync depot --- _mirror | 2 +- engine/art/audio/coin.wav | Bin 15154 -> 0 bytes engine/art/audio/larry.mid | Bin 15307 -> 0 bytes engine/art/audio/larry.txt | 38 ----------- engine/art/audio/monkey1.mid | Bin 29707 -> 0 bytes engine/art/audio/monkey1.txt | 43 ------------ engine/art/audio/pew.sfxr | Bin 105 -> 0 bytes engine/art/audio/waterworld-map.fur | Bin 2795 -> 0 bytes engine/art/audio/wrath_of_the_djinn.txt | 3 - engine/art/audio/wrath_of_the_djinn.xm | Bin 24403 -> 0 bytes engine/joint/v4k.h | 84 +++++++++++++----------- engine/split/3rd_archive.h | 8 ++- engine/split/v4k_cooker.c | 1 - engine/split/v4k_ds.h | 2 +- engine/split/v4k_editor.c | 9 +++ engine/split/v4k_file.c | 58 ++++++++-------- engine/split/v4k_math.c | 2 +- engine/split/v4k_scene.c | 2 +- engine/split/v4k_system.c | 2 +- engine/v4k | 8 ++- engine/v4k.c | 74 +++++++++++---------- engine/v4k.h | 2 +- 22 files changed, 136 insertions(+), 202 deletions(-) delete mode 100644 engine/art/audio/coin.wav delete mode 100644 engine/art/audio/larry.mid delete mode 100644 engine/art/audio/larry.txt delete mode 100644 engine/art/audio/monkey1.mid delete mode 100644 engine/art/audio/monkey1.txt delete mode 100644 engine/art/audio/pew.sfxr delete mode 100644 engine/art/audio/waterworld-map.fur delete mode 100644 engine/art/audio/wrath_of_the_djinn.txt delete mode 100644 engine/art/audio/wrath_of_the_djinn.xm diff --git a/_mirror b/_mirror index 5daf19e..be43196 160000 --- a/_mirror +++ b/_mirror @@ -1 +1 @@ -Subproject commit 5daf19e6b5579dfba7d5bc83d4b2c7db02e4c3a0 +Subproject commit be43196a3d33412a5dbad92983af7e149b1b066d diff --git a/engine/art/audio/coin.wav b/engine/art/audio/coin.wav deleted file mode 100644 index b0ca3e8f69c7524933e69cdfbed616f4f4ed09f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15154 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 diff --git a/engine/art/audio/larry.mid b/engine/art/audio/larry.mid deleted file mode 100644 index 3b886aa186280471471776f18726cbd449fdd6d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15307 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 diff --git a/engine/art/audio/waterworld-map.fur b/engine/art/audio/waterworld-map.fur deleted file mode 100644 index 2bf8a7af78bf33271550a1a603323531e42269b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2795 zcmbVMc|4T+9!^=tmg&ezB;%CrSUZQ5Wh`Y1F?B?iG+axKZIXQ~qsdYfvYl)*WZy!A z$u@I@GfB~q3__w|ELnyzjG4JZox6SR=l*g3d*9#hd7tI`eBN(Z-cr8R!($hYlDI?k zkE_q8&#MS4JlJ$q&<@xq*?rNb?o^tTDDkjtVN8rzy@FtbT&*AQy6^F+A2coYnVXrJ z{1E#IeHbA0!W58qreFnl@&19>gtKm{!l3NvORZkW<3{acgE*s&stqJc*JUGW@_kT0 zv9h%?f<+LmQp*>Ds$;={J1;9F$DmeDS=KCxC4{N>OfQ>zNV72v#Gi0k+-kM%!G@%{=ltlpEiDUXIfhbfr<>DOiJO?+aHO= z${Ygy_L^kn|IfP-E|)72zU@sJC-(Y$3lBZmv^s zkjd?OGEPgHy*Lcf;`Geba&?efo<&|mg9}cWCO<~Qf*@4Le|5d124nBP8MJDnb<4It zjDyPb)-bprZz-|q-)>L%Y|hOk%-C6f&IDBq(9;!NMr*=g!W_F+%6Kqgo_n6g>7(_X z%m2cX_&OFaocu-aIQY(|CBy(re->IDJ^yCDV%ja6osfK-<>8`Vqu4$>a}RsDWJ*50 zBdfaUCC#r6wH7Q$LIK$yggN|z5j6H&sgJ)aj1A|I%$d}6_L0`&7P8WW9n1;=o{B^DE)Y|*%@FD80 zaHmSUd9Q}HnhVisa1HDw40d9akrAGG?{k!A&A+IXWMb|%Xwn`CfiFOxFF6n+t z$7_yp7%fij__85+eEZ7Xel@X3>d3VZEuPSDyr(^jX+gJj+UN=W6xdV+-VEtW=)^o@ zs#^@F97^%7nR+xr@J!MI9T{%Rck7Q#GJQ;V{y`(+b*lz$lmyMe4v6%dIQ_m-9TImF zG5fLkwsW~*5@F>kLPpQ`l*Wjp|ADDOLrIqWS0BPq!9|$kLYC2&@hr!sY2~*PuLt#J z&JLW_)FKSHk6IUvRcoId&kY%$qmswk3pmt(G4^(?T(jI%HsX}Zz`xnOw-Wm@5KI^d zWSANDf{v}LHx7wVOOkWU-}zU1W+4TQ9xRC=l^Dh!ha(sM!?1jV@_USEJtGfh)Vx+7 zSSTHfBaiuU`^Ag8Nj|xpyH-!d4`Cm$B{p>@(U*&BtAl$nYyQ2}jMa3i&?@s&d8lZw4~+ld3?=Zklvm^Pt-H^j;N(fc~J7nMlpcM)dZRMQR~ zup1}EuO|Gfgh;%bv?itobiVB2>GPL)7q?e^1v>hk=Y;?DqHukpM*PrWu}gMrLIR!IVn_PxL0#8?4hg&5D$b_&y^iVv`K9CC^hQL?bRgvl03MtF9d$r^=$(JE z-Hn6uj%|4AKbG=*7`(LyIy@2NG3Yp(y1L1Tb=D2~3Va6zssmP;pc@JAE*VmRJfE0A zUL0YQxZpkJ=Tfn^vK}XZ{?Ha{?WqS*)Bv&|6`uTyuqN~$FLiiNWg{Z{MF(A_xlU3TQ%pzGp!J+V2S@!oK|Bw0nmm!kS zK=q5FX-AR|qvPPi6?oU%wI`r#K}}X|7$G$*XTq$hk>swFcr$~2|wld9hVe6!c|Tx%VTkMO(`dH*Zi;Uj+vj= z6TIwunWgzJzm@qUMC5y!qpIJ_{08EcnUt7z#a2qdwp=NOI0aIZJFu|Q%y_1{G8h*2h zTAOj{k)Q#)`mfeXECIVJ$Wm>IIqnh^L;jjd_XC_=8jRtVA-x_%EkT9P;O1bcoq#A= z)M!lb#RO1`t+~hT-_xX?Q+dpL$X{k?K(Qde)A_~>+leOAd3RY4_q?^zbEXrIBDs7- z_n9M3PVBghX=3mav(|>qoMkG))>m=w81&wNPZ`Zf!peWq6@z>6AR!@E>-8g50nqR1!a z8?oxxyx1oV#*T*FBiQPlIfjKz;w2n5@1$cBb8s=`XZg@GWuB`()o@~|@svAlRF z=4OB21LEX|ZFc&#o$1%ma1-FT=SlB61F5rbU_dHOq@!W!#F@Q3-&L_KY~~c>u|*GE zNKjl{hPR>OXY+W=I5hiKMdIFOdu0!NYWJroU_b9?%JmgcaPs_M0_3f<@fjxBoa`B| z(k+|dQav{b4h#6HMX{P#kCzF}n|8U$GRhGuGEQDX}CpDEPp6$r}h{|nnY%jMc6rN#Umwhf~e diff --git a/engine/art/audio/wrath_of_the_djinn.txt b/engine/art/audio/wrath_of_the_djinn.txt deleted file mode 100644 index b359515..0000000 --- a/engine/art/audio/wrath_of_the_djinn.txt +++ /dev/null @@ -1,3 +0,0 @@ -Licensed under the Public Domain license -Registered Artist(s): - Drozerix diff --git a/engine/art/audio/wrath_of_the_djinn.xm b/engine/art/audio/wrath_of_the_djinn.xm deleted file mode 100644 index 84c16b034c2c2c8e2e2bb698160a332b40864e67..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24403 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∈nOEn=?*yw& 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 awc-9n7dqejbnOp{#s^BeQYVdhB=SGTFQeN4 diff --git a/engine/joint/v4k.h b/engine/joint/v4k.h index f886324..3cc65d0 100644 --- a/engine/joint/v4k.h +++ b/engine/joint/v4k.h @@ -14757,7 +14757,7 @@ API void (map_clear)(map* m); API char *cc4str(unsigned cc); API char *cc8str(uint64_t cc); -enum { ///- +enum { # define _(a,b,c,d,e) cc__##a, cc__##b, cc__##c, cc__##d, cc__##e cc__1 = '1', _(2,3,4,5,6),_(7,8,9,0,_), cc__ = ' ', cc__A = 'A', _(B,C,D,E,F),_(G,H,I,J,K),_(L,M,N,O,P),_(Q,R,S,T,U),_(V,W,X,Y,Z), @@ -253747,8 +253747,9 @@ int dir_yield(dir *d, const char *pathfile, char *name, int namelen) { snprintf(name, namelen, "%s/*", pathfile); for( HANDLE h = FindFirstFileA(name, &fdata ); h != INVALID_HANDLE_VALUE; ok = (FindClose( h ), h = INVALID_HANDLE_VALUE, 1)) { for( int next = 1; next; next = FindNextFileA(h, &fdata) != 0 ) { - if( fdata.cFileName[0] == '.' ) continue; int is_dir = (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) > 0; + if( is_dir && fdata.cFileName[0] == '.' ) continue; + snprintf(name, namelen, "%s/%s%s", pathfile, fdata.cFileName, is_dir ? "/" : ""); struct stat st; if( !is_dir ) if(stat(name, &st) < 0) continue; // add @@ -253763,10 +253764,11 @@ int dir_yield(dir *d, const char *pathfile, char *name, int namelen) { snprintf(name, namelen, "%s/", pathfile); for( DIR *dir = opendir(name); dir; ok = (closedir(dir), dir = 0, 1)) { for( struct dirent *ep; (ep = readdir(dir)) != NULL; ) { - if( ep->d_name[0] == '.' ) continue; snprintf(name, namelen, "%s/%s", pathfile, ep->d_name); struct stat st; if( stat(name, &st) < 0 ) continue; - DIR *tmp = opendir(/*ep->d_*/name); int is_dir = !!tmp; if(tmp) closedir(tmp); + DIR *tmp = opendir(/*ep->d_*/name); int is_dir = !!tmp; if(tmp) closedir(tmp); // @todo:optimizeme (maybe use stat instead) + if( is_dir && ep->d_name[0] == '.' ) continue; + // add dir_entry de = { STRDUP(name), is_dir ? 0 : st.st_size, is_dir }; d->entry = (dir_entry*)REALLOC(d->entry, ++d->count * sizeof(dir_entry)); @@ -586455,7 +586457,6 @@ int cook_jobs() { return clampi(num_jobs, 0, cook_disabled?0:max_jobs); } - void cook_config( const char *pathfile_to_cook_ini ) { // @todo: test run-from-"bin/" case on Linux. COOK_INI = pathfile_to_cook_ini; ASSERT( file_exist(COOK_INI) ); @@ -587012,36 +587013,30 @@ const char** file_list(const char *cwd, const char *masks) { } array_resize(list, 0);//array_free(list); - for each_substring(masks,";",it) { - int recurse = !!strstr(it, "**"); - #if is(win32) - char *glob = va("dir %s/b/o:n \"%s\\%s\" 2> NUL", recurse ? "/s":"", cwd, it); - #else // linux, osx - char *glob = va("find %s %s -name \"%s\" | sort", cwd, !recurse ? "-maxdepth 1":"-type f", it); - #endif - for( FILE *in = popen(glob, "r"); in; pclose(in), in = 0) { - char buf[1024], *line = buf; - while( fgets(buf, sizeof(buf), in) ) { - // clean up - if( strstr(line, arg0) ) line = buf + larg0; - if( !memcmp(line, "./", 2) ) line += 2; - int len = strlen(line); while( len > 0 && line[len-1] < 32 ) line[--len] = 0; - if( line[0] == '\0' ) continue; - // do not insert system folders/files - for(int i = 0; i < len; ++i ) if(line[i] == '\\') line[i] = '/'; - if( line[0] == '.' ) if( !strcmp(line,".git") || !strcmp(line,".vs") || !strcmp(line,".") || !strcmp(line,"..") ) continue; - if( strstr(line, "/.") ) continue; + dir *d = dir_open(cwd, "rb"); + if( d ) { + for( int i = 0; i < dir_count(d); ++i ) { + if( dir_file(d,i) ) { + // dir_name() should return full normalized paths "C:/prj/v4k/demos/art/fx/fxBloom.fs". should exclude system dirs as well + char *entry = dir_name(d,i); + char *fname = file_name(entry); + + int allowed = 0; + for each_substring(masks,";",mask) { + allowed |= strmatch(fname, mask); + } + if( !allowed ) continue; + + // if( strstr(fname, "/.") ) continue; // @fixme: still needed? useful? + // insert copy - #if is(win32) - char *copy = STRDUP(line); // full path already provided - #else - // while(line[0] == '/') ++line; - char *copy = STRDUP(va("%s%s", cwd, line)); // need to prepend path - #endif + char *copy = STRDUP(entry); array_push(list, copy); } } + dir_close(d); } + array_push(list, 0); // terminator return (const char**)list; } @@ -587578,12 +587573,14 @@ if( found && *found == 0 ) { base = file_name(pathfile); if(base[0] == '\0') return 0; // it's a dir folder = file_path(pathfile); - // make folder variable easier to read in logs: /home/rlyeh/prj/v4k/art/demos/audio/coin.wav -> demos/audio/coin.wav - // static int ART_LEN = 0; do_once ART_LEN = strlen(ART); - // if( !strncmp(folder, ART, ART_LEN) ) { - // folder += ART_LEN; - // } - char* pretty_folder = folder && strlen(folder) >= ART_LEN ? folder + ART_LEN : ""; + // ease folders reading by shortening them: /home/rlyeh/prj/v4k/art/demos/audio/coin.wav -> demos/audio/coin.wav + // or C:/prj/v4k/engine/art/fonts/B612-BoldItalic.ttf -> fonts/B612-BoldItalic.ttf + static array(char*) art_paths = 0; + do_once for each_substring(ART,",",stem) array_push(art_paths, STRDUP(stem)); + char* pretty_folder = ""; + if( folder ) for( int i = 0; i < array_count(art_paths); ++i ) { + if( strbeg(folder, art_paths[i]) ) { pretty_folder = folder + strlen(art_paths[i]); break; } + } //} int size = 0; @@ -591809,7 +591806,7 @@ bool invert44(mat44 T, const mat44 M) { // !!! ok, i guess } vec4 transform444(const mat44, const vec4); -bool unproject44(vec3 *out, vec3 xyd, vec4 viewport, mat44 mvp) { +bool unproject44(vec3 *out, vec3 xyd, vec4 viewport, mat44 mvp) { // @fixme: this function is broken (verified by @zpl-zak) // xyd: usually x:mouse_x,y:window_height()-mouse_y,d:0=znear/1=zfar // src: https://www.khronos.org/opengl/wiki/GluProject_and_gluUnProject_code mat44 inv_mvp; @@ -600273,7 +600270,7 @@ void camera_fov(camera_t *cam, float fov) { float DIMETRIC = 30.000f; float ISOMETRIC = 35.264f; - float aspect = window_width() / ((float)window_height()+!!window_height()); + float aspect = window_width() / ((float)window_height()+!window_height()); orthogonal(cam->proj, 45, aspect, -1000, 1000); // why -1000? // cam->yaw = 45; cam->pitch = -ISOMETRIC; @@ -601991,7 +601988,7 @@ bool app_open_folder(const char *file) { #ifdef _WIN32 snprintf(buf, sizeof(buf), "start \"\" \"%s\"", file); #elif __APPLE__ - snprintf(buf, sizeof(buf), "%s \"%s\"", is_directory(file) ? "open" : "open --reveal", file); + snprintf(buf, sizeof(buf), "%s \"%s\"", file_directory(file) ? "open" : "open --reveal", file); #else snprintf(buf, sizeof(buf), "xdg-open \"%s\"", file); #endif @@ -606805,6 +606802,14 @@ char *editor_path(const char *path) { } vec3 editor_pick(float mouse_x, float mouse_y) { +#if 0 + // unproject 2d coord as 3d coord + camera_t *camera = camera_get_active(); + vec3 out, xyd = vec3(mouse_x,window_height()-mouse_y,1); // usually x:mouse_x,y:window_height()-mouse_y,d:0=znear/1=zfar + mat44 mvp, model; identity44(model); multiply44x3(mvp, camera->proj, camera->view, model); + bool ok = unproject44(&out, xyd, vec4(0,0,window_width(),window_height()), mvp); + return out; +#else // unproject 2d coord as 3d coord camera_t *camera = camera_get_active(); float x = (2.0f * mouse_x) / window_width() - 1.0f; @@ -606818,6 +606823,7 @@ vec3 editor_pick(float mouse_x, float mouse_y) { vec4 eye = vec4(p.x, p.y, -1.0, 0.0); vec4 wld = norm4(transform444(inv_view, eye)); return vec3(wld.x, wld.y, wld.z); +#endif } int editor_ui_bits8(const char *label, uint8_t *enabled) { // @to deprecate diff --git a/engine/split/3rd_archive.h b/engine/split/3rd_archive.h index 4d808a3..6f3fd2a 100644 --- a/engine/split/3rd_archive.h +++ b/engine/split/3rd_archive.h @@ -1471,8 +1471,9 @@ int dir_yield(dir *d, const char *pathfile, char *name, int namelen) { snprintf(name, namelen, "%s/*", pathfile); for( HANDLE h = FindFirstFileA(name, &fdata ); h != INVALID_HANDLE_VALUE; ok = (FindClose( h ), h = INVALID_HANDLE_VALUE, 1)) { for( int next = 1; next; next = FindNextFileA(h, &fdata) != 0 ) { - if( fdata.cFileName[0] == '.' ) continue; int is_dir = (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) > 0; + if( is_dir && fdata.cFileName[0] == '.' ) continue; + snprintf(name, namelen, "%s/%s%s", pathfile, fdata.cFileName, is_dir ? "/" : ""); struct stat st; if( !is_dir ) if(stat(name, &st) < 0) continue; // add @@ -1487,10 +1488,11 @@ int dir_yield(dir *d, const char *pathfile, char *name, int namelen) { snprintf(name, namelen, "%s/", pathfile); for( DIR *dir = opendir(name); dir; ok = (closedir(dir), dir = 0, 1)) { for( struct dirent *ep; (ep = readdir(dir)) != NULL; ) { - if( ep->d_name[0] == '.' ) continue; snprintf(name, namelen, "%s/%s", pathfile, ep->d_name); struct stat st; if( stat(name, &st) < 0 ) continue; - DIR *tmp = opendir(/*ep->d_*/name); int is_dir = !!tmp; if(tmp) closedir(tmp); + DIR *tmp = opendir(/*ep->d_*/name); int is_dir = !!tmp; if(tmp) closedir(tmp); // @todo:optimizeme (maybe use stat instead) + if( is_dir && ep->d_name[0] == '.' ) continue; + // add dir_entry de = { STRDUP(name), is_dir ? 0 : st.st_size, is_dir }; d->entry = (dir_entry*)REALLOC(d->entry, ++d->count * sizeof(dir_entry)); diff --git a/engine/split/v4k_cooker.c b/engine/split/v4k_cooker.c index 26d7f7e..c56d921 100644 --- a/engine/split/v4k_cooker.c +++ b/engine/split/v4k_cooker.c @@ -817,7 +817,6 @@ int cook_jobs() { return clampi(num_jobs, 0, cook_disabled?0:max_jobs); } - void cook_config( const char *pathfile_to_cook_ini ) { // @todo: test run-from-"bin/" case on Linux. COOK_INI = pathfile_to_cook_ini; ASSERT( file_exist(COOK_INI) ); diff --git a/engine/split/v4k_ds.h b/engine/split/v4k_ds.h index dbcb47d..03b53d1 100644 --- a/engine/split/v4k_ds.h +++ b/engine/split/v4k_ds.h @@ -433,7 +433,7 @@ API void (map_clear)(map* m); API char *cc4str(unsigned cc); API char *cc8str(uint64_t cc); -enum { ///- +enum { # define _(a,b,c,d,e) cc__##a, cc__##b, cc__##c, cc__##d, cc__##e cc__1 = '1', _(2,3,4,5,6),_(7,8,9,0,_), cc__ = ' ', cc__A = 'A', _(B,C,D,E,F),_(G,H,I,J,K),_(L,M,N,O,P),_(Q,R,S,T,U),_(V,W,X,Y,Z), diff --git a/engine/split/v4k_editor.c b/engine/split/v4k_editor.c index 300b202..5cb221b 100644 --- a/engine/split/v4k_editor.c +++ b/engine/split/v4k_editor.c @@ -6,6 +6,14 @@ char *editor_path(const char *path) { } vec3 editor_pick(float mouse_x, float mouse_y) { +#if 0 + // unproject 2d coord as 3d coord + camera_t *camera = camera_get_active(); + vec3 out, xyd = vec3(mouse_x,window_height()-mouse_y,1); // usually x:mouse_x,y:window_height()-mouse_y,d:0=znear/1=zfar + mat44 mvp, model; identity44(model); multiply44x3(mvp, camera->proj, camera->view, model); + bool ok = unproject44(&out, xyd, vec4(0,0,window_width(),window_height()), mvp); + return out; +#else // unproject 2d coord as 3d coord camera_t *camera = camera_get_active(); float x = (2.0f * mouse_x) / window_width() - 1.0f; @@ -19,6 +27,7 @@ vec3 editor_pick(float mouse_x, float mouse_y) { vec4 eye = vec4(p.x, p.y, -1.0, 0.0); vec4 wld = norm4(transform444(inv_view, eye)); return vec3(wld.x, wld.y, wld.z); +#endif } int editor_ui_bits8(const char *label, uint8_t *enabled) { // @to deprecate diff --git a/engine/split/v4k_file.c b/engine/split/v4k_file.c index 48d8b39..47d45b4 100644 --- a/engine/split/v4k_file.c +++ b/engine/split/v4k_file.c @@ -212,36 +212,30 @@ const char** file_list(const char *cwd, const char *masks) { } array_resize(list, 0);//array_free(list); - for each_substring(masks,";",it) { - int recurse = !!strstr(it, "**"); - #if is(win32) - char *glob = va("dir %s/b/o:n \"%s\\%s\" 2> NUL", recurse ? "/s":"", cwd, it); - #else // linux, osx - char *glob = va("find %s %s -name \"%s\" | sort", cwd, !recurse ? "-maxdepth 1":"-type f", it); - #endif - for( FILE *in = popen(glob, "r"); in; pclose(in), in = 0) { - char buf[1024], *line = buf; - while( fgets(buf, sizeof(buf), in) ) { - // clean up - if( strstr(line, arg0) ) line = buf + larg0; - if( !memcmp(line, "./", 2) ) line += 2; - int len = strlen(line); while( len > 0 && line[len-1] < 32 ) line[--len] = 0; - if( line[0] == '\0' ) continue; - // do not insert system folders/files - for(int i = 0; i < len; ++i ) if(line[i] == '\\') line[i] = '/'; - if( line[0] == '.' ) if( !strcmp(line,".git") || !strcmp(line,".vs") || !strcmp(line,".") || !strcmp(line,"..") ) continue; - if( strstr(line, "/.") ) continue; + dir *d = dir_open(cwd, "rb"); + if( d ) { + for( int i = 0; i < dir_count(d); ++i ) { + if( dir_file(d,i) ) { + // dir_name() should return full normalized paths "C:/prj/v4k/demos/art/fx/fxBloom.fs". should exclude system dirs as well + char *entry = dir_name(d,i); + char *fname = file_name(entry); + + int allowed = 0; + for each_substring(masks,";",mask) { + allowed |= strmatch(fname, mask); + } + if( !allowed ) continue; + + // if( strstr(fname, "/.") ) continue; // @fixme: still needed? useful? + // insert copy - #if is(win32) - char *copy = STRDUP(line); // full path already provided - #else - // while(line[0] == '/') ++line; - char *copy = STRDUP(va("%s%s", cwd, line)); // need to prepend path - #endif + char *copy = STRDUP(entry); array_push(list, copy); } } + dir_close(d); } + array_push(list, 0); // terminator return (const char**)list; } @@ -778,12 +772,14 @@ if( found && *found == 0 ) { base = file_name(pathfile); if(base[0] == '\0') return 0; // it's a dir folder = file_path(pathfile); - // make folder variable easier to read in logs: /home/rlyeh/prj/v4k/art/demos/audio/coin.wav -> demos/audio/coin.wav - // static int ART_LEN = 0; do_once ART_LEN = strlen(ART); - // if( !strncmp(folder, ART, ART_LEN) ) { - // folder += ART_LEN; - // } - char* pretty_folder = folder && strlen(folder) >= ART_LEN ? folder + ART_LEN : ""; + // ease folders reading by shortening them: /home/rlyeh/prj/v4k/art/demos/audio/coin.wav -> demos/audio/coin.wav + // or C:/prj/v4k/engine/art/fonts/B612-BoldItalic.ttf -> fonts/B612-BoldItalic.ttf + static array(char*) art_paths = 0; + do_once for each_substring(ART,",",stem) array_push(art_paths, STRDUP(stem)); + char* pretty_folder = ""; + if( folder ) for( int i = 0; i < array_count(art_paths); ++i ) { + if( strbeg(folder, art_paths[i]) ) { pretty_folder = folder + strlen(art_paths[i]); break; } + } //} int size = 0; diff --git a/engine/split/v4k_math.c b/engine/split/v4k_math.c index 85ecbc1..bf23946 100644 --- a/engine/split/v4k_math.c +++ b/engine/split/v4k_math.c @@ -821,7 +821,7 @@ bool invert44(mat44 T, const mat44 M) { // !!! ok, i guess } vec4 transform444(const mat44, const vec4); -bool unproject44(vec3 *out, vec3 xyd, vec4 viewport, mat44 mvp) { +bool unproject44(vec3 *out, vec3 xyd, vec4 viewport, mat44 mvp) { // @fixme: this function is broken (verified by @zpl-zak) // xyd: usually x:mouse_x,y:window_height()-mouse_y,d:0=znear/1=zfar // src: https://www.khronos.org/opengl/wiki/GluProject_and_gluUnProject_code mat44 inv_mvp; diff --git a/engine/split/v4k_scene.c b/engine/split/v4k_scene.c index 3c2da04..86dd766 100644 --- a/engine/split/v4k_scene.c +++ b/engine/split/v4k_scene.c @@ -109,7 +109,7 @@ void camera_fov(camera_t *cam, float fov) { float DIMETRIC = 30.000f; float ISOMETRIC = 35.264f; - float aspect = window_width() / ((float)window_height()+!!window_height()); + float aspect = window_width() / ((float)window_height()+!window_height()); orthogonal(cam->proj, 45, aspect, -1000, 1000); // why -1000? // cam->yaw = 45; cam->pitch = -ISOMETRIC; diff --git a/engine/split/v4k_system.c b/engine/split/v4k_system.c index a3cb685..979feff 100644 --- a/engine/split/v4k_system.c +++ b/engine/split/v4k_system.c @@ -823,7 +823,7 @@ bool app_open_folder(const char *file) { #ifdef _WIN32 snprintf(buf, sizeof(buf), "start \"\" \"%s\"", file); #elif __APPLE__ - snprintf(buf, sizeof(buf), "%s \"%s\"", is_directory(file) ? "open" : "open --reveal", file); + snprintf(buf, sizeof(buf), "%s \"%s\"", file_directory(file) ? "open" : "open --reveal", file); #else snprintf(buf, sizeof(buf), "xdg-open \"%s\"", file); #endif diff --git a/engine/v4k b/engine/v4k index e63fd7a..e9dae6e 100644 --- a/engine/v4k +++ b/engine/v4k @@ -235686,8 +235686,9 @@ int dir_yield(dir *d, const char *pathfile, char *name, int namelen) { snprintf(name, namelen, "%s/*", pathfile); for( HANDLE h = FindFirstFileA(name, &fdata ); h != INVALID_HANDLE_VALUE; ok = (FindClose( h ), h = INVALID_HANDLE_VALUE, 1)) { for( int next = 1; next; next = FindNextFileA(h, &fdata) != 0 ) { - if( fdata.cFileName[0] == '.' ) continue; int is_dir = (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) > 0; + if( is_dir && fdata.cFileName[0] == '.' ) continue; + snprintf(name, namelen, "%s/%s%s", pathfile, fdata.cFileName, is_dir ? "/" : ""); struct stat st; if( !is_dir ) if(stat(name, &st) < 0) continue; // add @@ -235702,10 +235703,11 @@ int dir_yield(dir *d, const char *pathfile, char *name, int namelen) { snprintf(name, namelen, "%s/", pathfile); for( DIR *dir = opendir(name); dir; ok = (closedir(dir), dir = 0, 1)) { for( struct dirent *ep; (ep = readdir(dir)) != NULL; ) { - if( ep->d_name[0] == '.' ) continue; snprintf(name, namelen, "%s/%s", pathfile, ep->d_name); struct stat st; if( stat(name, &st) < 0 ) continue; - DIR *tmp = opendir(/*ep->d_*/name); int is_dir = !!tmp; if(tmp) closedir(tmp); + DIR *tmp = opendir(/*ep->d_*/name); int is_dir = !!tmp; if(tmp) closedir(tmp); // @todo:optimizeme (maybe use stat instead) + if( is_dir && ep->d_name[0] == '.' ) continue; + // add dir_entry de = { STRDUP(name), is_dir ? 0 : st.st_size, is_dir }; d->entry = (dir_entry*)REALLOC(d->entry, ++d->count * sizeof(dir_entry)); diff --git a/engine/v4k.c b/engine/v4k.c index 2440ecb..3cb40b3 100644 --- a/engine/v4k.c +++ b/engine/v4k.c @@ -4631,7 +4631,6 @@ int cook_jobs() { return clampi(num_jobs, 0, cook_disabled?0:max_jobs); } - void cook_config( const char *pathfile_to_cook_ini ) { // @todo: test run-from-"bin/" case on Linux. COOK_INI = pathfile_to_cook_ini; ASSERT( file_exist(COOK_INI) ); @@ -5188,36 +5187,30 @@ const char** file_list(const char *cwd, const char *masks) { } array_resize(list, 0);//array_free(list); - for each_substring(masks,";",it) { - int recurse = !!strstr(it, "**"); - #if is(win32) - char *glob = va("dir %s/b/o:n \"%s\\%s\" 2> NUL", recurse ? "/s":"", cwd, it); - #else // linux, osx - char *glob = va("find %s %s -name \"%s\" | sort", cwd, !recurse ? "-maxdepth 1":"-type f", it); - #endif - for( FILE *in = popen(glob, "r"); in; pclose(in), in = 0) { - char buf[1024], *line = buf; - while( fgets(buf, sizeof(buf), in) ) { - // clean up - if( strstr(line, arg0) ) line = buf + larg0; - if( !memcmp(line, "./", 2) ) line += 2; - int len = strlen(line); while( len > 0 && line[len-1] < 32 ) line[--len] = 0; - if( line[0] == '\0' ) continue; - // do not insert system folders/files - for(int i = 0; i < len; ++i ) if(line[i] == '\\') line[i] = '/'; - if( line[0] == '.' ) if( !strcmp(line,".git") || !strcmp(line,".vs") || !strcmp(line,".") || !strcmp(line,"..") ) continue; - if( strstr(line, "/.") ) continue; + dir *d = dir_open(cwd, "rb"); + if( d ) { + for( int i = 0; i < dir_count(d); ++i ) { + if( dir_file(d,i) ) { + // dir_name() should return full normalized paths "C:/prj/v4k/demos/art/fx/fxBloom.fs". should exclude system dirs as well + char *entry = dir_name(d,i); + char *fname = file_name(entry); + + int allowed = 0; + for each_substring(masks,";",mask) { + allowed |= strmatch(fname, mask); + } + if( !allowed ) continue; + + // if( strstr(fname, "/.") ) continue; // @fixme: still needed? useful? + // insert copy - #if is(win32) - char *copy = STRDUP(line); // full path already provided - #else - // while(line[0] == '/') ++line; - char *copy = STRDUP(va("%s%s", cwd, line)); // need to prepend path - #endif + char *copy = STRDUP(entry); array_push(list, copy); } } + dir_close(d); } + array_push(list, 0); // terminator return (const char**)list; } @@ -5754,12 +5747,14 @@ if( found && *found == 0 ) { base = file_name(pathfile); if(base[0] == '\0') return 0; // it's a dir folder = file_path(pathfile); - // make folder variable easier to read in logs: /home/rlyeh/prj/v4k/art/demos/audio/coin.wav -> demos/audio/coin.wav - // static int ART_LEN = 0; do_once ART_LEN = strlen(ART); - // if( !strncmp(folder, ART, ART_LEN) ) { - // folder += ART_LEN; - // } - char* pretty_folder = folder && strlen(folder) >= ART_LEN ? folder + ART_LEN : ""; + // ease folders reading by shortening them: /home/rlyeh/prj/v4k/art/demos/audio/coin.wav -> demos/audio/coin.wav + // or C:/prj/v4k/engine/art/fonts/B612-BoldItalic.ttf -> fonts/B612-BoldItalic.ttf + static array(char*) art_paths = 0; + do_once for each_substring(ART,",",stem) array_push(art_paths, STRDUP(stem)); + char* pretty_folder = ""; + if( folder ) for( int i = 0; i < array_count(art_paths); ++i ) { + if( strbeg(folder, art_paths[i]) ) { pretty_folder = folder + strlen(art_paths[i]); break; } + } //} int size = 0; @@ -9985,7 +9980,7 @@ bool invert44(mat44 T, const mat44 M) { // !!! ok, i guess } vec4 transform444(const mat44, const vec4); -bool unproject44(vec3 *out, vec3 xyd, vec4 viewport, mat44 mvp) { +bool unproject44(vec3 *out, vec3 xyd, vec4 viewport, mat44 mvp) { // @fixme: this function is broken (verified by @zpl-zak) // xyd: usually x:mouse_x,y:window_height()-mouse_y,d:0=znear/1=zfar // src: https://www.khronos.org/opengl/wiki/GluProject_and_gluUnProject_code mat44 inv_mvp; @@ -18449,7 +18444,7 @@ void camera_fov(camera_t *cam, float fov) { float DIMETRIC = 30.000f; float ISOMETRIC = 35.264f; - float aspect = window_width() / ((float)window_height()+!!window_height()); + float aspect = window_width() / ((float)window_height()+!window_height()); orthogonal(cam->proj, 45, aspect, -1000, 1000); // why -1000? // cam->yaw = 45; cam->pitch = -ISOMETRIC; @@ -20167,7 +20162,7 @@ bool app_open_folder(const char *file) { #ifdef _WIN32 snprintf(buf, sizeof(buf), "start \"\" \"%s\"", file); #elif __APPLE__ - snprintf(buf, sizeof(buf), "%s \"%s\"", is_directory(file) ? "open" : "open --reveal", file); + snprintf(buf, sizeof(buf), "%s \"%s\"", file_directory(file) ? "open" : "open --reveal", file); #else snprintf(buf, sizeof(buf), "xdg-open \"%s\"", file); #endif @@ -24981,6 +24976,14 @@ char *editor_path(const char *path) { } vec3 editor_pick(float mouse_x, float mouse_y) { +#if 0 + // unproject 2d coord as 3d coord + camera_t *camera = camera_get_active(); + vec3 out, xyd = vec3(mouse_x,window_height()-mouse_y,1); // usually x:mouse_x,y:window_height()-mouse_y,d:0=znear/1=zfar + mat44 mvp, model; identity44(model); multiply44x3(mvp, camera->proj, camera->view, model); + bool ok = unproject44(&out, xyd, vec4(0,0,window_width(),window_height()), mvp); + return out; +#else // unproject 2d coord as 3d coord camera_t *camera = camera_get_active(); float x = (2.0f * mouse_x) / window_width() - 1.0f; @@ -24994,6 +24997,7 @@ vec3 editor_pick(float mouse_x, float mouse_y) { vec4 eye = vec4(p.x, p.y, -1.0, 0.0); vec4 wld = norm4(transform444(inv_view, eye)); return vec3(wld.x, wld.y, wld.z); +#endif } int editor_ui_bits8(const char *label, uint8_t *enabled) { // @to deprecate diff --git a/engine/v4k.h b/engine/v4k.h index 78e11ec..e171346 100644 --- a/engine/v4k.h +++ b/engine/v4k.h @@ -824,7 +824,7 @@ API void (map_clear)(map* m); API char *cc4str(unsigned cc); API char *cc8str(uint64_t cc); -enum { ///- +enum { # define _(a,b,c,d,e) cc__##a, cc__##b, cc__##c, cc__##d, cc__##e cc__1 = '1', _(2,3,4,5,6),_(7,8,9,0,_), cc__ = ' ', cc__A = 'A', _(B,C,D,E,F),_(G,H,I,J,K),_(L,M,N,O,P),_(Q,R,S,T,U),_(V,W,X,Y,Z),