int ur_readDir( UThread* ut, const char* filename, UCell* res ) { char filespec[ _MAX_PATH ]; struct _finddata_t fileinfo; intptr_t handle; // Look for all files. We ensure there is a slash before the wildcard. // It's OK if the path is already terminated with a slash - multiple // slashes are filtered by _findfirst. strcpy( filespec, filename ); strcat( filespec, "\\*.*" ); handle = _findfirst( filespec, &fileinfo ); if( handle != -1 ) { UCell* cell; UIndex blkN; UIndex hold; UIndex strN; blkN = ur_makeBlock( ut, 0 ); hold = ur_hold( blkN ); do { const char* cp = fileinfo.name; if( cp[0] == '.' && (cp[1] == '.' || cp[1] == '\0') ) continue; strN = ur_makeStringUtf8( ut, (const uint8_t*) cp, (const uint8_t*) (cp + strlen(cp)) ); cell = ur_blkAppendNew( ur_buffer(blkN), UT_FILE ); ur_setSeries( cell, strN, 0 ); } while( _findnext( handle, &fileinfo ) != -1 ); _findclose( handle ); ur_release( hold ); ur_setId(res, UT_BLOCK); ur_setSeries(res, blkN, 0); } else { ur_setId(res, UT_LOGIC); ur_int(res) = 0; } return UR_OK; }
static int ledit_select( GWidget* wp, UAtom atom, UCell* res ) { if( atom == UR_ATOM_TEXT ) { EX_PTR; ur_setId(res, UT_STRING); ur_setSeries(res, ep->strN, 0); return UR_OK; } else if( atom == UR_ATOM_ACTION ) { EX_PTR; ur_setId(res, UT_BLOCK); ur_setSeries(res, ep->codeN, 0); return UR_OK; } return gui_areaSelect( wp, atom, res ); }
/** Generate a single binary and set cell to reference it. If you need multiple buffers then ur_genBuffers() should be used. \param size Number of bytes to reserve. \param cell Cell to initialize. \return Pointer to binary buffer. */ UBuffer* ur_makeBinaryCell( UThread* ut, int size, UCell* cell ) { UBuffer* buf; UIndex bufN; ur_genBuffers( ut, 1, &bufN ); buf = ur_buffer( bufN ); ur_binInit( buf, size ); ur_setId( cell, UT_BINARY ); ur_setSeries( cell, bufN, 0 ); return buf; }
/* Sets res to either a shader! or a context! whose first value is a shader!. Returns UR_OK/UR_THROW. */ int ur_makeShader( UThread* ut, const char* vert, const char* frag, UCell* res ) { #define MAX_SHADER_PARAM 16 // LIMIT: User parameters per shader. Shader shad; Shader* sh; UIndex bufN; UBuffer* buf; int i; char name[ 128 ]; ShaderParam param[ MAX_SHADER_PARAM ]; ShaderParam* pi; GLsizei length; GLint size; GLenum type; GLint count = 0; if( ! createShader( ut, &shad, vert, frag ) ) return UR_THROW; glGetProgramiv( shad.program, GL_ACTIVE_UNIFORMS, &count ); // Collect non-gl parameters. pi = param; for( i = 0; i < count; ++i ) { glGetActiveUniform( shad.program, i, 128, &length, &size, &type, name ); if( name[0] == 'g' && name[1] == 'l' && name[2] == '_' ) continue; pi->type = type; pi->location = glGetUniformLocation( shad.program, name ); pi->name = ur_internAtom( ut, name, name + length ); if( pi->name == UR_INVALID_ATOM ) return UR_THROW; ++pi; } count = pi - param; if( count ) { ShaderParam* pend; UBuffer* ctx; UCell* cval; // We have parameters - make context to hold shader & params. ctx = ur_makeContextCell( ut, count + 1, res ); cval = ur_ctxAddWord( ctx, UR_ATOM_SHADER ); pi = param; pend = param + count; while( pi != pend ) { cval = ur_ctxAddWord( ctx, pi->name ); #if 0 printf( "KR Shader Param %d is type %d\n", (int) (pi - param), pi->type ); #endif switch( pi->type ) { case GL_FLOAT: ur_setId( cval, UT_DECIMAL ); ur_decimal( cval ) = 0.0; break; case GL_FLOAT_VEC2: case GL_FLOAT_VEC3: //case GL_FLOAT_VEC4: ur_setId( cval, UT_VEC3 ); cval->vec3.xyz[0] = cval->vec3.xyz[1] = cval->vec3.xyz[2] = 0.0f; break; case GL_INT: ur_setId( cval, UT_INT ); ur_int( cval ) = 0; break; case GL_INT_VEC2: case GL_INT_VEC3: //case GL_INT_VEC4: ur_setId( cval, UT_COORD ); break; case GL_BOOL: ur_setId( cval, UT_LOGIC ); ur_int( cval ) = 0; break; case GL_SAMPLER_2D: case GL_SAMPLER_CUBE: #ifndef GL_ES_VERSION_2_0 case GL_SAMPLER_1D: case GL_SAMPLER_3D: case GL_SAMPLER_1D_SHADOW: case GL_SAMPLER_2D_SHADOW: #endif ur_setId( cval, UT_NONE ); ur_texId(cval) = 0; // Expecting texture!. break; #ifdef GL_ES_VERSION_2_0 case GL_FLOAT_MAT4: ur_setId( cval, UT_NONE ); break; #endif default: ur_setId( cval, UT_NONE ); break; /* GL_BOOL_VEC2: GL_BOOL_VEC3: GL_BOOL_VEC4: GL_FLOAT_MAT2: GL_FLOAT_MAT3: GL_FLOAT_MAT4: GL_SAMPLER_2D_RECT: GL_SAMPLER_2D_RECT_SHADOW: */ } ++pi; } ur_ctxSort( ctx ); } ur_genBuffers( ut, 1, &bufN ); buf = ur_buffer( bufN ); buf->type = UT_SHADER; buf->ptr.v = memAlloc( sizeof(Shader) + sizeof(ShaderParam) * (count - 1) ); sh = (Shader*) buf->ptr.v; sh->program = shad.program; sh->paramCount = count; if( count ) { memCpy( sh->param, param, sizeof(ShaderParam) * count ); // First context value will be set to shader!. res = ur_buffer( res->series.buf )->ptr.cell; } ur_setId( res, UT_SHADER ); ur_setSeries( res, bufN, 0 ); return UR_OK; }
static void ledit_layout( GWidget* wp ) { UCell* style = glEnv.guiStyle; UThread* ut = glEnv.guiUT; UCell* rc; EX_PTR; // Set draw list variables. rc = style + CI_STYLE_LABEL; ur_setId( rc, UT_STRING ); ur_setSeries( rc, ep->strN, 0 ); rc = style + CI_STYLE_AREA; gui_initRectCoord( rc, wp, UR_ATOM_RECT ); // Compile draw lists. if( ! gDPC ) return; // Make sure the tgeo vertex buffers are bound before the switch. // Otherwise only the first case would emit the code to do it. // NOTE: This assumes the button draw programs actually use tgeo. dp_tgeoInit( gDPC ); ep->dpSwitch = dp_beginSwitch( gDPC, 2 ); rc = style + CI_STYLE_EDITOR; if( ur_is(rc, UT_BLOCK) ) ur_compileDP( ut, rc, 1 ); dp_endCase( gDPC, ep->dpSwitch ); rc = style + CI_STYLE_EDITOR_ACTIVE; if( ur_is(rc, UT_BLOCK) ) ur_compileDP( ut, rc, 1 ); dp_endCase( gDPC, ep->dpSwitch ); dp_endSwitch( gDPC, ep->dpSwitch, ep->state ); setFlag( CHANGED ); #if 0 rc = style + CI_STYLE_EDITOR_CURSOR; if( ur_is(rc, UT_BLOCK) ) { DPCompiler dc; DPCompiler* save; save = gx_beginDP( &dc ); if( save ) dc.shaderProg = save->shaderProg; ur_compileDP( ut, rc, 1 ); gx_endDP( ur_buffer( ep->textResN ), save ); //dp_compile( &dc, ut, rc->series.n ); } #endif }