add angle

This commit is contained in:
ShirosakiMio 2022-12-07 19:53:48 +08:00
parent 6c2c3a2d70
commit c59d299f5d
18 changed files with 15448 additions and 107 deletions

View File

@ -8,7 +8,8 @@ public class FCLConfig implements Serializable {
public enum Renderer implements Serializable {
RENDERER_GL4ES("libgl4es.so:libgl4es_egl.so"),
RENDERER_ZINK("libGL.so:libEGL.so");
RENDERER_ZINK("libGL.so:libEGL.so"),
RENDERER_ANGLE("lib.so:libEGL_angle.so");
private final String glInfo;
private String glVersion;

View File

@ -140,6 +140,9 @@ public class FCLauncher {
if (renderer.getGlVersion() != null) {
envMap.put("LIBGL_GL", renderer.getGlVersion());
}
if("libtinywrapper.so".equals(renderer.getGlLibName())) {
envMap.put("LIBGL_ES","3");
}
envMap.put("LIBGL_MIPMAP", "3");
envMap.put("LIBGL_NORMALIZE", "1");
envMap.put("LIBGL_VSYNC", "1");

View File

@ -1,5 +1,17 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := angle_gles2
LOCAL_SRC_FILES := tinywrapper/angle-gles/$(TARGET_ARCH_ABI)/libGLESv2_angle.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := tinywrapper
LOCAL_SHARED_LIBRARIES := angle_gles2
LOCAL_SRC_FILES := tinywrapper/main.c tinywrapper/string_utils.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)/tinywrapper
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := xhook
LOCAL_SRC_FILES := xhook/xhook.c \

View File

@ -277,6 +277,8 @@ GLFWbool _glfwInitEGL(void)
_glfw_dlsym(_glfw.egl.handle, "eglGetConfigAttrib");
_glfw.egl.GetConfigs = (PFN_eglGetConfigs)
_glfw_dlsym(_glfw.egl.handle, "eglGetConfigs");
_glfw.egl.ChooseConfig = (PFN_eglChooseConfig)
_glfw_dlsym(_glfw.egl.handle, "eglChooseConfig");
_glfw.egl.GetDisplay = (PFN_eglGetDisplay)
_glfw_dlsym(_glfw.egl.handle, "eglGetDisplay");
_glfw.egl.GetError = (PFN_eglGetError)
@ -382,12 +384,6 @@ void _glfwTerminateEGL(void)
}
}
#define setAttrib(a, v) \
{ \
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
attribs[index++] = a; \
attribs[index++] = v; \
}
// Create the OpenGL or OpenGL ES context
//
@ -395,10 +391,8 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
EGLint attribs[40];
EGLConfig config;
EGLConfig config=malloc(sizeof(EGLConfig));
EGLContext share = NULL;
int index = 0;
if (!_glfw.egl.display)
{
@ -409,13 +403,33 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
if (ctxconfig->share)
share = ctxconfig->share->context.egl.handle;
if (!chooseEGLConfig(ctxconfig, fbconfig, &config))
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"EGL: Failed to find a suitable EGLConfig");
EGLint egl_attributes[] = {
EGL_BLUE_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_RED_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_DEPTH_SIZE, 24,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT|0x0001,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE
};
EGLint num_configs = 0;
const EGLint egl_context_attributes[] = { EGL_CONTEXT_CLIENT_VERSION, getenv("LIBGL_ES"), EGL_NONE };
if (eglChooseConfig(_glfw.egl.display, egl_attributes, NULL, 0, &num_configs) != GLFW_TRUE) {
_glfwInputError(GLFW_API_UNAVAILABLE, "eglChooseConfig() failed: %04x",
eglGetError());
return GLFW_FALSE;
}
if (num_configs == 0) {
_glfwInputError(GLFW_API_UNAVAILABLE, "%s",
"eglChooseConfig() found no matching config");
return GLFW_FALSE;
}
eglChooseConfig(_glfw.egl.display, egl_attributes, &config, 1, &num_configs);
// eglGetConfigAttrib(_glfw.egl.display, config, EGL_NATIVE_VISUAL_ID, 0);
if (ctxconfig->client == GLFW_OPENGL_ES_API)
{
if (!eglBindAPI(EGL_OPENGL_ES_API))
@ -437,82 +451,8 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
}
}
if (_glfw.egl.KHR_create_context)
{
int mask = 0, flags = 0;
if (ctxconfig->client == GLFW_OPENGL_API)
{
if (ctxconfig->forward)
flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
mask |= EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
mask |= EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR;
}
if (ctxconfig->debug)
flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
if (ctxconfig->robustness)
{
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
{
setAttrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
EGL_NO_RESET_NOTIFICATION_KHR);
}
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
{
setAttrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
EGL_LOSE_CONTEXT_ON_RESET_KHR);
}
flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
}
if (ctxconfig->noerror)
{
if (_glfw.egl.KHR_create_context_no_error)
setAttrib(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE);
}
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
{
setAttrib(EGL_CONTEXT_MAJOR_VERSION_KHR, ctxconfig->major);
setAttrib(EGL_CONTEXT_MINOR_VERSION_KHR, ctxconfig->minor);
}
if (mask)
setAttrib(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask);
if (flags)
setAttrib(EGL_CONTEXT_FLAGS_KHR, flags);
}
else
{
if (ctxconfig->client == GLFW_OPENGL_ES_API)
setAttrib(EGL_CONTEXT_CLIENT_VERSION, ctxconfig->major);
}
if (_glfw.egl.KHR_context_flush_control)
{
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
{
setAttrib(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR,
EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR);
}
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
{
setAttrib(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR,
EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR);
}
}
setAttrib(EGL_NONE, EGL_NONE);
window->context.egl.handle = eglCreateContext(_glfw.egl.display,
config, share, attribs);
config, share, egl_context_attributes);
if (window->context.egl.handle == EGL_NO_CONTEXT)
{
@ -522,25 +462,11 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
return GLFW_FALSE;
}
// Set up attributes for surface creation
index = 0;
if (fbconfig->sRGB)
{
if (_glfw.egl.KHR_gl_colorspace)
setAttrib(EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR);
}
if (!fbconfig->doublebuffer)
setAttrib(EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER);
setAttrib(EGL_NONE, EGL_NONE);
window->context.egl.surface =
eglCreateWindowSurface(_glfw.egl.display,
config,
_GLFW_EGL_NATIVE_WINDOW,
attribs);
NULL);
if (window->context.egl.surface == EGL_NO_SURFACE)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
@ -548,7 +474,6 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
getEGLErrorString(eglGetError()));
return GLFW_FALSE;
}
window->context.egl.config = config;
// Load the appropriate client library
@ -567,7 +492,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
};
const char* glsonames[] =
{
"libgl4es.so",
getenv("LIBGL_NAME"),
};
if (ctxconfig->client == GLFW_OPENGL_ES_API)
@ -610,7 +535,6 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
return GLFW_TRUE;
}
#undef setAttrib
//////////////////////////////////////////////////////////////////////////

View File

@ -79,6 +79,7 @@ typedef void* EGLSurface;
// EGL function pointer typedefs
typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigAttrib)(EGLDisplay,EGLConfig,EGLint,EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigs)(EGLDisplay,EGLConfig*,EGLint,EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglChooseConfig)(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
typedef EGLDisplay (EGLAPIENTRY * PFN_eglGetDisplay)(EGLNativeDisplayType);
typedef EGLint (EGLAPIENTRY * PFN_eglGetError)(void);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglInitialize)(EGLDisplay,EGLint*,EGLint*);
@ -95,6 +96,7 @@ typedef const char* (EGLAPIENTRY * PFN_eglQueryString)(EGLDisplay,EGLint);
typedef GLFWglproc (EGLAPIENTRY * PFN_eglGetProcAddress)(const char*);
#define eglGetConfigAttrib _glfw.egl.GetConfigAttrib
#define eglGetConfigs _glfw.egl.GetConfigs
#define eglChooseConfig _glfw.egl.ChooseConfig
#define eglGetDisplay _glfw.egl.GetDisplay
#define eglGetError _glfw.egl.GetError
#define eglInitialize _glfw.egl.Initialize
@ -144,6 +146,7 @@ typedef struct _GLFWlibraryEGL
PFN_eglGetConfigAttrib GetConfigAttrib;
PFN_eglGetConfigs GetConfigs;
PFN_eglChooseConfig ChooseConfig;
PFN_eglGetDisplay GetDisplay;
PFN_eglGetError GetError;
PFN_eglInitialize Initialize;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,201 @@
//#import <Foundation/Foundation.h>
#include <stdio.h>
#include <dlfcn.h>
#include "gl.h"
#include "GLES3/gl32.h"
#include "string_utils.h"
#define LOOKUP_FUNC(func) \
if (!gles_##func) { \
gles_##func = dlsym(RTLD_NEXT, #func); \
} if (!gles_##func) { \
gles_##func = dlsym(RTLD_DEFAULT, #func); \
}
int proxy_width, proxy_height, proxy_intformat, maxTextureSize;
void glBindFragDataLocationEXT(GLuint program, GLuint colorNumber, const char * name);
void(*gles_glGetTexLevelParameteriv)(GLenum target, GLint level, GLenum pname, GLint *params);
void(*gles_glShaderSource)(GLuint shader, GLsizei count, const GLchar * const *string, const GLint *length);
void(*gles_glTexImage2D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *data);
void glBindFragDataLocation(GLuint program, GLuint colorNumber, const char * name) {
glBindFragDataLocationEXT(program, colorNumber, name);
}
void glClearDepth(GLdouble depth) {
glClearDepthf(depth);
}
void *glMapBuffer(GLenum target, GLenum access) {
// Use: GL_EXT_map_buffer_range
GLenum access_range;
GLint length;
switch (target) {
// GL 4.2
case GL_ATOMIC_COUNTER_BUFFER:
// GL 4.3
case GL_DISPATCH_INDIRECT_BUFFER:
case GL_SHADER_STORAGE_BUFFER :
// GL 4.4
case GL_QUERY_BUFFER:
printf("ERROR: glMapBuffer unsupported target=0x%x", target);
break; // not supported for now
case GL_DRAW_INDIRECT_BUFFER:
case GL_TEXTURE_BUFFER:
printf("ERROR: glMapBuffer unimplemented target=0x%x", target);
break;
}
switch (access) {
case GL_READ_ONLY:
access_range = GL_MAP_READ_BIT;
break;
case GL_WRITE_ONLY:
access_range = GL_MAP_WRITE_BIT;
break;
case GL_READ_WRITE:
access_range = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
break;
}
glGetBufferParameteriv(target, GL_BUFFER_SIZE, &length);
return glMapBufferRange(target, 0, length, access_range);
}
void glShaderSource(GLuint shader, GLsizei count, const GLchar * const *string, const GLint *length) {
LOOKUP_FUNC(glShaderSource)
// DBG(printf("glShaderSource(%d, %d, %p, %p)\n", shader, count, string, length);)
char *source = NULL;
char *converted;
// get the size of the shader sources and than concatenate in a single string
int l = 0;
for (int i=0; i<count; i++) l+=(length && length[i] >= 0)?length[i]:strlen(string[i]);
if (source) free(source);
source = calloc(1, l+1);
if(length) {
for (int i=0; i<count; i++) {
if(length[i] >= 0)
strncat(source, string[i], length[i]);
else
strcat(source, string[i]);
}
} else {
for (int i=0; i<count; i++)
strcat(source, string[i]);
}
char *source2 = strchr(source, '#');
if (!source2) {
source2 = source;
}
// are there #version?
if (!strncmp(source2, "#version ", 9)) {
converted = strdup(source2);
if (converted[9] == '1') {
if (converted[10] - '0' < 2) {
// 100, 110 -> 120
converted[10] = '2';
} else if (converted[10] - '0' < 6) {
// 130, 140, 150 -> 330
converted[9] = converted[10] = '3';
}
}
// remove "core", is it safe?
if (!strncmp(&converted[13], "core", 4)) {
strncpy(&converted[13], "\n//c", 4);
}
} else {
converted = calloc(1, strlen(source) + 13);
strcpy(converted, "#version 120\n");
strcpy(&converted[13], strdup(source));
}
int convertedLen = strlen(converted);
#ifdef __APPLE__
// patch OptiFine 1.17.x
if (FindString(converted, "\nuniform mat4 textureMatrix = mat4(1.0);")) {
InplaceReplace(converted, &convertedLen, "\nuniform mat4 textureMatrix = mat4(1.0);", "\n#define textureMatrix mat4(1.0)");
}
#endif
// some needed exts
const char* extensions =
"#extension GL_EXT_blend_func_extended : enable\n"
// For OptiFine (see patch above)
"#extension GL_EXT_shader_non_constant_global_initializers : enable\n";
converted = InplaceInsert(GetLine(converted, 1), extensions, converted, &convertedLen);
gles_glShaderSource(shader, 1, (const GLchar * const*)((converted)?(&converted):(&source)), NULL);
free(source);
free(converted);
}
int isProxyTexture(GLenum target) {
switch (target) {
case GL_PROXY_TEXTURE_1D:
case GL_PROXY_TEXTURE_2D:
case GL_PROXY_TEXTURE_3D:
case GL_PROXY_TEXTURE_RECTANGLE_ARB:
return 1;
}
return 0;
}
static int inline nlevel(int size, int level) {
if(size) {
size>>=level;
if(!size) size=1;
}
return size;
}
void glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) {
LOOKUP_FUNC(glGetTexLevelParameteriv)
// NSLog("glGetTexLevelParameteriv(%x, %d, %x, %p)", target, level, pname, params);
if (isProxyTexture(target)) {
switch (pname) {
case GL_TEXTURE_WIDTH:
(*params) = nlevel(proxy_width,level);
break;
case GL_TEXTURE_HEIGHT:
(*params) = nlevel(proxy_height,level);
break;
case GL_TEXTURE_INTERNAL_FORMAT:
(*params) = proxy_intformat;
break;
}
} else {
gles_glGetTexLevelParameteriv(target, level, pname, params);
}
}
void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *data) {
LOOKUP_FUNC(glTexImage2D)
if (isProxyTexture(target)) {
if (!maxTextureSize) {
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
// maxTextureSize = 16384;
// NSLog(@"Maximum texture size: %d", maxTextureSize);
}
proxy_width = ((width<<level)>maxTextureSize)?0:width;
proxy_height = ((height<<level)>maxTextureSize)?0:height;
proxy_intformat = internalformat;
// swizzle_internalformat((GLenum *) &internalformat, format, type);
} else {
gles_glTexImage2D(target, level, internalformat, width, height, border, format, type, data);
}
}

View File

@ -0,0 +1,234 @@
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "string_utils.h"
const char* AllSeparators = " \t\n\r.,;()[]{}-<>+*/%&\\\"'^$=!:?";
char* ResizeIfNeeded(char* pBuffer, int *size, int addsize);
char* InplaceReplace(char* pBuffer, int* size, const char* S, const char* D)
{
int lS = strlen(S), lD = strlen(D);
pBuffer = ResizeIfNeeded(pBuffer, size, (lD-lS)*CountString(pBuffer, S));
char* p = pBuffer;
while((p = strstr(p, S)))
{
// found an occurence of S
// check if good to replace, strchr also found '\0' :)
if(strchr(AllSeparators, p[lS])!=NULL && (p==pBuffer || strchr(AllSeparators, p[-1])!=NULL)) {
// move out rest of string
memmove(p+lD, p+lS, strlen(p)-lS+1);
// replace
memcpy(p, D, strlen(D));
// next
p+=lD;
} else p+=lS;
}
return pBuffer;
}
char* InplaceInsert(char* pBuffer, const char* S, char* master, int* size)
{
char* m = ResizeIfNeeded(master, size, strlen(S));
if(m!=master) {
pBuffer += (m-master);
master = m;
}
char* p = pBuffer;
int lS = strlen(S), ll = strlen(pBuffer);
memmove(p+lS, p, ll+1);
memcpy(p, S, lS);
return master;
}
char* GetLine(char* pBuffer, int num)
{
char *p = pBuffer;
while(num-- && (p=strstr(p, "\n"))) p+=strlen("\n");
return (p)?p:pBuffer;
}
int CountLine(const char* pBuffer)
{
int n=0;
const char* p = pBuffer;
while((p=strstr(p, "\n"))) {
p+=strlen("\n");
n++;
}
return n;
}
int GetLineFor(const char* pBuffer, const char* S)
{
int n=0;
const char* p = pBuffer;
const char* end = FindString(pBuffer, S);
if(!end)
return 0;
while((p=strstr(p, "\n"))) {
p+=strlen("\n");
n++;
if(p>=end)
return n;
}
return n;
}
int CountString(const char* pBuffer, const char* S)
{
const char* p = pBuffer;
int lS = strlen(S);
int n = 0;
while((p = strstr(p, S)))
{
// found an occurence of S
// check if good to count, strchr also found '\0' :)
if(strchr(AllSeparators, p[lS])!=NULL && (p==pBuffer || strchr(AllSeparators, p[-1])!=NULL))
n++;
p+=lS;
}
return n;
}
const char* FindString(const char* pBuffer, const char* S)
{
const char* p = pBuffer;
int lS = strlen(S);
while((p = strstr(p, S)))
{
// found an occurence of S
// check if good to count, strchr also found '\0' :)
if(strchr(AllSeparators, p[lS])!=NULL && (p==pBuffer || strchr(AllSeparators, p[-1])!=NULL))
return p;
p+=lS;
}
return NULL;
}
char* FindStringNC(char* pBuffer, const char* S)
{
char* p = pBuffer;
int lS = strlen(S);
while((p = strstr(p, S)))
{
// found an occurence of S
// check if good to count, strchr also found '\0' :)
if(strchr(AllSeparators, p[lS])!=NULL && (p==pBuffer || strchr(AllSeparators, p[-1])!=NULL))
return p;
p+=lS;
}
return NULL;
}
char* ResizeIfNeeded(char* pBuffer, int *size, int addsize) {
char* p = pBuffer;
int newsize = strlen(pBuffer)+addsize+1;
if (newsize>*size) {
newsize += 100;
p = (char*)realloc(pBuffer, newsize);
*size=newsize;
}
return p;
}
char* Append(char* pBuffer, int* size, const char* S) {
char* p =pBuffer;
p = ResizeIfNeeded(pBuffer, size, strlen(S));
strcat(p, S);
return p;
}
int isBlank(char c) {
switch(c) {
case ' ':
case '\t':
case '\n':
case '\r':
case ':':
case ',':
case ';':
case '/':
return 1;
default:
return 0;
}
}
char* StrNext(char *pBuffer, const char* S) {
if(!pBuffer) return NULL;
char *p = strstr(pBuffer, S);
return (p)?p:(p+strlen(S));
}
char* NextStr(char* pBuffer) {
if(!pBuffer) return NULL;
while(isBlank(*pBuffer))
++pBuffer;
return pBuffer;
}
char* NextBlank(char* pBuffer) {
if(!pBuffer) return NULL;
while(!isBlank(*pBuffer))
++pBuffer;
return pBuffer;
}
char* NextLine(char* pBuffer) {
if(!pBuffer) return NULL;
while(*pBuffer && *pBuffer!='\n')
++pBuffer;
return pBuffer;
}
const char* GetNextStr(char* pBuffer) {
static char buff[100] = {0};
buff[0] = '\0';
if(!pBuffer) return NULL;
char* p1 = NextStr(pBuffer);
if(!p1) return buff;
char* p2 = NextBlank(p1);
if(!p2) return buff;
int i=0;
while(p1!=p2 && i<99)
buff[i++] = *(p1++);
buff[i] = '\0';
return buff;
}
int CountStringSimple(char* pBuffer, const char* S)
{
char* p = pBuffer;
int lS = strlen(S);
int n = 0;
while((p = strstr(p, S)))
{
// found an occurence of S
n++;
p+=lS;
}
return n;
}
char* InplaceReplaceSimple(char* pBuffer, int* size, const char* S, const char* D)
{
int lS = strlen(S), lD = strlen(D);
pBuffer = ResizeIfNeeded(pBuffer, size, (lD-lS)*CountStringSimple(pBuffer, S));
char* p = pBuffer;
while((p = strstr(p, S)))
{
// found an occurence of S
// move out rest of string
memmove(p+lD, p+lS, strlen(p)-lS+1);
// replace
memcpy(p, D, strlen(D));
// next
p+=lD;
}
return pBuffer;
}

View File

@ -0,0 +1,29 @@
#ifndef _GL4ES_STRING_UTILS_H_
#define _GL4ES_STRING_UTILS_H_
extern const char* AllSeparators;
const char* FindString(const char* pBuffer, const char* S);
char* FindStringNC(char* pBuffer, const char* S);
int CountString(const char* pBuffer, const char* S);
char* ResizeIfNeeded(char* pBuffer, int *size, int addsize);
char* InplaceReplace(char* pBuffer, int* size, const char* S, const char* D);
char* Append(char* pBuffer, int* size, const char* S);
char* InplaceInsert(char* pBuffer, const char* S, char* master, int* size);
char* GetLine(char* pBuffer, int num);
int CountLine(const char* pBuffer);
int GetLineFor(const char* pBuffer, const char* S); // get the line number for 1st occurent of S in pBuffer
char* StrNext(char *pBuffer, const char* S); // mostly as strstr, but go after the substring if found
//"blank" (space, tab, cr, lf,":", ",", ";", ".", "/")
char* NextStr(char* pBuffer); // go to next non "blank"
char* NextBlank(char* pBuffer); // go to next "blank"
char* NextLine(char* pBuffer); // go to next new line (crlf not included)
const char* GetNextStr(char* pBuffer); // get a (static) copy of next str (until next separator), can be a simple number or separator also
// those function don't try to be smart with separators...
int CountStringSimple(char* pBuffer, const char* S);
char* InplaceReplaceSimple(char* pBuffer, int* size, const char* S, const char* D);
#endif // _GL4ES_STRING_UTILS_H_

Binary file not shown.

Binary file not shown.

Binary file not shown.