progress
This commit is contained in:
@@ -4,6 +4,7 @@ cargs = [
|
|||||||
'-std=c99',
|
'-std=c99',
|
||||||
'-Og',
|
'-Og',
|
||||||
'-g',
|
'-g',
|
||||||
|
'-DBOUNDS_CHECK'
|
||||||
]
|
]
|
||||||
|
|
||||||
dependencies = []
|
dependencies = []
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
#include "DynArray.h"
|
#include "DynArray.h"
|
||||||
|
|
||||||
DYN_ARRAY_IMPL(DynString);
|
DYN_ARRAY_IMPL(DynString, DynString);
|
||||||
|
|||||||
100
src/DynArray.h
100
src/DynArray.h
@@ -7,57 +7,105 @@
|
|||||||
|
|
||||||
#include "DynString.h"
|
#include "DynString.h"
|
||||||
|
|
||||||
#define DYN_ARRAY_EXPANDER(macro, args) macro args
|
#ifdef BOUNDS_CHECK
|
||||||
|
|
||||||
#define DYN_ARRAY_IMPL(type) \
|
#include "log.h"
|
||||||
DYN_ARRAY_ALLOC(type, DynArray_##type, DynArray_##type##_alloc) \
|
|
||||||
DYN_ARRAY_PUSH_BACK(type, DynArray_##type, DynArray_##type##_push_back) \
|
|
||||||
|
|
||||||
#define DYN_ARRAY_SIGS(type) \
|
#endif // BOUNDS_CHECK
|
||||||
DYN_ARRAY_ALLOC_SIG(DynArray_##type, DynArray_##type##_alloc); \
|
|
||||||
DYN_ARRAY_PUSH_BACK_SIG(type, DynArray_##type, DynArray_##type##_push_back); \
|
|
||||||
|
|
||||||
#define DYN_ARRAY_STRUCT(type) \
|
#define DYN_ARRAY_EXPANDER(macro, type, type_name, func_name) macro(type, DynArray_##type_name, DynArray_##type_name##_##func_name);
|
||||||
typedef struct { \
|
|
||||||
|
#define DYN_ARRAY_IMPL(type, type_name) \
|
||||||
|
DYN_ARRAY_EXPANDER(DYN_ARRAY_ALLOC, type, type_name, alloc) \
|
||||||
|
DYN_ARRAY_EXPANDER(DYN_ARRAY_IS_NULL, type, type_name, is_null) \
|
||||||
|
DYN_ARRAY_EXPANDER(DYN_ARRAY_PUSH_BACK, type, type_name, push_back) \
|
||||||
|
DYN_ARRAY_EXPANDER(DYN_ARRAY_AT, type, type_name, at)
|
||||||
|
|
||||||
|
#define DYN_ARRAY_HEADER(type, type_name) \
|
||||||
|
DYN_ARRAY_STRUCT(type, type_name) \
|
||||||
|
DYN_ARRAY_SIGS(type, type_name)
|
||||||
|
|
||||||
|
#define DYN_ARRAY_SIGS(type, type_name) \
|
||||||
|
DYN_ARRAY_EXPANDER(DYN_ARRAY_ALLOC_SIG, type, type_name, alloc) \
|
||||||
|
DYN_ARRAY_EXPANDER(DYN_ARRAY_IS_NULL_SIG, type, type_name, is_null) \
|
||||||
|
DYN_ARRAY_EXPANDER(DYN_ARRAY_PUSH_BACK_SIG, type, type_name, push_back) \
|
||||||
|
DYN_ARRAY_EXPANDER(DYN_ARRAY_AT_SIG, type, type_name, at)
|
||||||
|
|
||||||
|
// DYN_ARRAY_ALLOC_SIG(type, DynArray_##type_name, DynArray_##type_name##_alloc); \
|
||||||
|
// DYN_ARRAY_PUSH_BACK_SIG(type, DynArray_##type_name, DynArray_##type_name##_push_back);
|
||||||
|
|
||||||
|
#define DYN_ARRAY_STRUCT(type, type_name) \
|
||||||
|
typedef struct { \
|
||||||
type* data; \
|
type* data; \
|
||||||
size_t count; \
|
size_t len; \
|
||||||
size_t capacity; \
|
size_t capacity; \
|
||||||
} DynArray_##type
|
} DynArray_##type_name;
|
||||||
|
|
||||||
// DYN_ARRAY_STRUCT(DynString);
|
// DYN_ARRAY_STRUCT(int);
|
||||||
|
|
||||||
#define DYN_ARRAY_ALLOC_SIG(type_name, func_name) int func_name(type_name* darr, const size_t capacity)
|
#define DYN_ARRAY_ALLOC_SIG(type, type_name, func_name) int func_name(type_name* darr)
|
||||||
|
|
||||||
#define DYN_ARRAY_ALLOC(type, type_name, func_name) \
|
#define DYN_ARRAY_ALLOC(type, type_name, func_name) \
|
||||||
DYN_ARRAY_ALLOC_SIG(type_name, func_name) { \
|
DYN_ARRAY_ALLOC_SIG(type, type_name, func_name) { \
|
||||||
darr->data = (type*) calloc(capacity, sizeof(type)); \
|
darr->data = (type*) calloc(1, sizeof(type)); \
|
||||||
if (darr->data == NULL) { \
|
if (darr->data == NULL) { \
|
||||||
return -1; \
|
return -1; \
|
||||||
} \
|
} \
|
||||||
darr->count = 0; \
|
darr->len = 0; \
|
||||||
darr->capacity = capacity; \
|
darr->capacity = 1; \
|
||||||
return 1; \
|
return 1; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DYN_ARRAY_IS_NULL_SIG(type, type_name, func_name) bool func_name(const type_name* darr)
|
||||||
|
|
||||||
|
#define DYN_ARRAY_IS_NULL(type, type_name, func_name) \
|
||||||
|
DYN_ARRAY_IS_NULL_SIG(type, type_name, func_name) { \
|
||||||
|
return darr->data == NULL; \
|
||||||
|
}
|
||||||
|
|
||||||
|
// DYN_ARRAY_ALLOC(int, DynArray_int, DynArray_int_alloc);
|
||||||
|
|
||||||
#define DYN_ARRAY_PUSH_BACK_SIG(type, type_name, func_name) int func_name(type_name* darr, const type* new_elem)
|
#define DYN_ARRAY_PUSH_BACK_SIG(type, type_name, func_name) int func_name(type_name* darr, const type* new_elem)
|
||||||
|
|
||||||
#define DYN_ARRAY_PUSH_BACK(type, type_name, func_name) \
|
#define DYN_ARRAY_PUSH_BACK(type, type_name, func_name) \
|
||||||
DYN_ARRAY_PUSH_BACK_SIG(type, type_name, func_name) { \
|
DYN_ARRAY_PUSH_BACK_SIG(type, type_name, func_name) { \
|
||||||
if (darr->count + 1 > darr->capacity) { \
|
if (darr->len + 1 > darr->capacity) { \
|
||||||
darr->capacity *= 2; \
|
darr->capacity *= 2; \
|
||||||
darr->data = (type*) realloc(darr->data, darr->capacity * sizeof(type)); \
|
darr->data = (type*) realloc(darr->data, darr->capacity * sizeof(type)); \
|
||||||
if (darr->data == NULL) { \
|
if (darr->data == NULL) { \
|
||||||
return -1; \
|
return -1; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
memcpy(darr->data + darr->count, new_elem, sizeof(type)); \
|
memcpy(darr->data + darr->len, new_elem, sizeof(type)); \
|
||||||
darr->count++; \
|
darr->len++; \
|
||||||
return 1; \
|
return 1; \
|
||||||
}
|
}
|
||||||
|
|
||||||
// DYN_ARRAY_PUSH_BACK(DynString, DynArray_DynString, DynArray_DynString_push_back);
|
#define DYN_ARRAY_AT_SIG(type, type_name, func_name) type* func_name(type_name* darr, const size_t i)
|
||||||
|
|
||||||
DYN_ARRAY_STRUCT(DynString);
|
#ifdef BOUNDS_CHECK
|
||||||
DYN_ARRAY_SIGS(DynString);
|
|
||||||
|
#define DYN_ARRAY_AT(type, type_name, func_name) \
|
||||||
|
DYN_ARRAY_AT_SIG(type, type_name, func_name) { \
|
||||||
|
if (i < 0 || i > darr->len) { \
|
||||||
|
LOG_FATALF(#func_name " exceeded bounds! i: %zu, len: %zu", i, darr->len); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
return &darr->data[i]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define DYN_ARRAY_AT(type, type_name, func_name) \
|
||||||
|
DYN_ARRAY_AT_SIG(type, type_name, func_name) { \
|
||||||
|
return darr->data[i]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // BOUNDS_CHECK
|
||||||
|
|
||||||
|
// DYN_ARRAY_PUSH_BACK(int, DynArray_int, DynArray_int_push_back);
|
||||||
|
|
||||||
|
DYN_ARRAY_HEADER(DynString, DynString);
|
||||||
|
DYN_ARRAY_HEADER(char*, charp);
|
||||||
|
|
||||||
#endif // DYN_ARRAY_H_
|
#endif // DYN_ARRAY_H_
|
||||||
|
|||||||
@@ -1,17 +1,49 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "DynString.h"
|
#include "DynString.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
short DynString_alloc(DynString* dstr, const char* str, const size_t len) {
|
DynString DynString_alloc(const char* str, const size_t len) {
|
||||||
dstr->data = (char*) malloc(sizeof(char) * len + 1);
|
DynString dstr = {
|
||||||
if (dstr->data == NULL) {
|
.data = (char*) malloc(sizeof(char) * len),
|
||||||
return -1;
|
.len = len
|
||||||
|
};
|
||||||
|
if (dstr.data == NULL) {
|
||||||
|
LOG_FATAL("Ran out of memory");
|
||||||
}
|
}
|
||||||
dstr->data = memcpy(dstr->data, str, len);
|
dstr.data = memcpy(dstr.data, str, len);
|
||||||
dstr->data[len] = '\0';
|
|
||||||
dstr->len = len;
|
|
||||||
|
|
||||||
return 1;
|
return dstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DynString_free(DynString* dstr) {
|
||||||
|
if (dstr->data != NULL) {
|
||||||
|
free(dstr->data);
|
||||||
|
}
|
||||||
|
dstr->len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DynString_is_null(const DynString* dstr) {
|
||||||
|
return dstr->data == NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DynString_equal(const DynString* s1, const DynString* s2) {
|
||||||
|
if (s1->len != s2->len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s1->data == NULL || s2->data == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < s1->len; i++) {
|
||||||
|
if (s1->data[i] != s2->data[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,18 @@
|
|||||||
#define DYN_STRING_H_
|
#define DYN_STRING_H_
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#define DYN_STRING_FMT(dstr) (int) (dstr).len, (dstr).data
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char* data;
|
char* data;
|
||||||
size_t len;
|
size_t len;
|
||||||
} DynString;
|
} DynString;
|
||||||
|
|
||||||
short DynString_alloc(DynString* dstr, const char* str, const size_t len);
|
DynString DynString_alloc(const char* str, const size_t len);
|
||||||
|
void DynString_free(DynString* dstr);
|
||||||
|
bool DynString_is_null(const DynString* dstr);
|
||||||
|
bool DynString_equal(const DynString* s1, const DynString* s2);
|
||||||
|
|
||||||
#endif // DYN_STRING_H_
|
#endif // DYN_STRING_H_
|
||||||
|
|||||||
@@ -2,10 +2,14 @@
|
|||||||
#define LOG_H_
|
#define LOG_H_
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define LOG_ERROR(str) log_error(__FILE__, __LINE__, (str))
|
#define LOG_ERROR(str) log_error(__FILE__, __LINE__, (str))
|
||||||
#define LOG_ERRORF(fmt, ...) log_errorf(__FILE__, __LINE__, (fmt), __VA_ARGS__)
|
#define LOG_ERRORF(fmt, ...) log_errorf(__FILE__, __LINE__, (fmt), __VA_ARGS__)
|
||||||
|
|
||||||
|
#define LOG_FATAL(str) LOG_ERROR(str); exit(-1);
|
||||||
|
#define LOG_FATALF(fmt, ...) LOG_ERRORF(fmt, __VA_ARGS__); exit(-1);
|
||||||
|
|
||||||
void log_error(char* file, size_t line, char* str);
|
void log_error(char* file, size_t line, char* str);
|
||||||
void log_errorf(char* file, size_t line, char* fmt, ...);
|
void log_errorf(char* file, size_t line, char* fmt, ...);
|
||||||
|
|
||||||
|
|||||||
93
src/main.c
93
src/main.c
@@ -14,6 +14,9 @@
|
|||||||
#include "DynString.h"
|
#include "DynString.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
HMODULE opengl_module = NULL;
|
HMODULE opengl_module = NULL;
|
||||||
|
|
||||||
// int _main() {
|
// int _main() {
|
||||||
@@ -22,6 +25,8 @@ HMODULE opengl_module = NULL;
|
|||||||
|
|
||||||
// #ifdef __MINGW32__
|
// #ifdef __MINGW32__
|
||||||
|
|
||||||
|
DynArray_DynString wgl_extensions = { 0 };
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char* msg;
|
const char* msg;
|
||||||
int num;
|
int num;
|
||||||
@@ -44,6 +49,34 @@ void* gl_function_load(const char* name) {
|
|||||||
return gl_func;
|
return gl_func;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool has_wgl_extension(const DynString* name) {
|
||||||
|
assert(!DynString_is_null(name));
|
||||||
|
assert(!DynArray_DynString_is_null(&wgl_extensions));
|
||||||
|
|
||||||
|
for (size_t i = 0; i < wgl_extensions.len; i++) {
|
||||||
|
if (DynString_equal(name, DynArray_DynString_at(&wgl_extensions, i))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has_wgl_extension_c_str(const char* name) {
|
||||||
|
DynString name_dstr = DynString_alloc(name, strlen(name));
|
||||||
|
const bool res = has_wgl_extension(&name_dstr);
|
||||||
|
DynString_free(&name_dstr);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct timespec thread_time_get() {
|
||||||
|
struct timespec t = { 0 };
|
||||||
|
if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t) == -1) {
|
||||||
|
LOG_FATALF("Failed to get thread time. errno: %d", errno);
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
void OnSize(HWND hwnd, UINT flag, int width, int height) {
|
void OnSize(HWND hwnd, UINT flag, int width, int height) {
|
||||||
printf("Window resize: flag: %d, width: %d, height: %d\n", flag, width, height);
|
printf("Window resize: flag: %d, width: %d, height: %d\n", flag, width, height);
|
||||||
}
|
}
|
||||||
@@ -149,63 +182,47 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// const char* wgl_extensions = wglGetExtensionsStringARB(hdc);
|
char* wgl_extensions_str = (char*) wglGetExtensionsStringARB(hdc);
|
||||||
char* wgl_extensions = (char*) wglGetExtensionsStringARB(hdc);
|
printf("wgl extensions: %s\n", wgl_extensions_str);
|
||||||
printf("wgl extensions: %s\n", wgl_extensions);
|
|
||||||
|
|
||||||
DynArray_DynString extensions_arr = { 0 };
|
char* wgl_extensions_str_copy = strdup(wgl_extensions_str);
|
||||||
if (!DynArray_DynString_alloc(&extensions_arr, 1)) {
|
|
||||||
LOG_ERROR("Failed to allocate");
|
if (!DynArray_DynString_alloc(&wgl_extensions)) {
|
||||||
|
LOG_ERROR("Failed to allocate wgl_extensions");
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* wgl_extensions_copy = strdup(wgl_extensions);
|
char* ext = strtok(wgl_extensions_str_copy, " ");
|
||||||
|
|
||||||
char* ext = strtok(wgl_extensions_copy, " ");
|
|
||||||
if (ext == NULL) {
|
if (ext == NULL) {
|
||||||
LOG_ERROR("wgl_extensions was empty");
|
LOG_ERROR("wgl_extensions_str was empty");
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
DynString ext_dstr = { 0 };
|
|
||||||
if (!DynString_alloc(&ext_dstr, ext, strlen(ext))) {
|
|
||||||
LOG_ERROR("Failed to allocate extension string");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
while (ext != NULL) {
|
||||||
|
DynString ext_dstr = DynString_alloc(ext, strlen(ext));
|
||||||
|
|
||||||
if (!DynArray_DynString_push_back(&extensions_arr, &ext_dstr)) {
|
if (!DynArray_DynString_push_back(&wgl_extensions, &ext_dstr)) {
|
||||||
LOG_ERROR("Failed to push back extension string");
|
LOG_ERROR("Failed to push back extension string");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
// printf("ext: %s\n", ext);
|
|
||||||
while (true) {
|
|
||||||
ext = strtok(NULL, " ");
|
ext = strtok(NULL, " ");
|
||||||
// printf("ext: %s\n", ext);
|
|
||||||
if (ext == NULL) {
|
if (ext == NULL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
DynString ext_dstr = { 0 };
|
|
||||||
if (!DynString_alloc(&ext_dstr, ext, strlen(ext))) {
|
|
||||||
LOG_ERROR("Failed to allocate extension string");
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!DynArray_DynString_push_back(&extensions_arr, &ext_dstr)) {
|
free(wgl_extensions_str_copy);
|
||||||
LOG_ERROR("Failed to push back extension string");
|
|
||||||
return 1;
|
for (size_t i = 0; i < wgl_extensions.len; i++) {
|
||||||
}
|
const DynString* ext = DynArray_DynString_at(&wgl_extensions, i);
|
||||||
|
printf("%.*s\n", DYN_STRING_FMT(*ext));
|
||||||
}
|
}
|
||||||
|
|
||||||
free(wgl_extensions_copy);
|
const struct timespec b = thread_time_get();
|
||||||
|
has_wgl_extension_c_str("WGL_ARB_create_context");
|
||||||
printf("count: %zu\n", extensions_arr.count);
|
const struct timespec a = thread_time_get();
|
||||||
for (size_t i = 0; i < extensions_arr.count; i++) {
|
printf("time: %ld\n", a.tv_nsec - b.tv_nsec);
|
||||||
printf("%s\n", extensions_arr.data[i].data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// glClearColor(1.0, 1.0, 0.0, 1.0);
|
|
||||||
// glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
// const unsigned char* version = glGetString(GL_VERSION);
|
|
||||||
// printf("OpenGL version %s\n", version);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user