diff --git a/src/data/test.txt b/src/data/test.txt deleted file mode 100644 index 924806b..0000000 --- a/src/data/test.txt +++ /dev/null @@ -1 +0,0 @@ -boo \ No newline at end of file diff --git a/src/koa/etc.c b/src/koa/etc.c index a0f2f9e..1fc022e 100644 --- a/src/koa/etc.c +++ b/src/koa/etc.c @@ -19,4 +19,30 @@ void mfree(int n, ...) { } va_end(args); +} + +uint8_t* _ord(uint8_t* buf, int length, int le) { + static int end_chk = -1; + if(end_chk == -1) { + uint16_t chk = 0xB00B; + end_chk = ((uint8_t*)&chk)[0] == 0x0B; + } + + if((end_chk && le) || (!end_chk && !le)) + return buf; + + uint8_t tmp[8] = { 0 }; + for(int i = 0; i < length; ++i) + tmp[i] = buf[length - i - 1]; + memcpy(buf, tmp, length); + + return buf; +} + +uint8_t* ltoh(uint8_t* buf, int length) { + return _ord(buf, length, 1); +} + +uint8_t* btoh(uint8_t* buf, int length) { + return _ord(buf, length, 0); } \ No newline at end of file diff --git a/src/koa/etc.h b/src/koa/etc.h index f43302e..5134ebf 100644 --- a/src/koa/etc.h +++ b/src/koa/etc.h @@ -1,9 +1,13 @@ #ifndef KOA_ETC_H #define KOA_ETC_H +#include +#include #include #include void mfree(int n, ...); +uint8_t* ltoh(uint8_t*, int); +uint8_t* btoh(uint8_t*, int); #endif diff --git a/src/koa/file.c b/src/koa/file.c index 676464b..76e73f0 100644 --- a/src/koa/file.c +++ b/src/koa/file.c @@ -60,3 +60,135 @@ char* file_read(const char* file) { return content; } + +int _bmp_load_metadata(FILE* fp, bmp_meta_t* out) { + + + return 1; +} + +int bmp_load_metadata(const char* file, bmp_meta_t* out) { + FILE* fp = fopen(file, "rb"); + if(fp == NULL) + return 0; + + uint8_t buffer[4] = { 0 }; + fread(buffer, 1, 2, fp); + if(memcmp("BM", buffer, 2) != 0) + return 0; + + fread(buffer, 1, 4, fp); + out->size = *(uint32_t*)ltoh(buffer, 4); + + fseek(fp, 0, SEEK_END); + if(ftell(fp) != out->size) + return 0; + + fseek(fp, 0x0A, SEEK_SET); + fread(buffer, 1, 4, fp); + out->header_size = *(uint32_t*)ltoh(buffer, 4); + out->body_size = out->size - out->header_size; + + fseek(fp, 0x12, SEEK_SET); + fread(buffer, 1, 4, fp); + out->width = *(uint32_t*)ltoh(buffer, 4); + fread(buffer, 1, 4, fp); + out->height = *(uint32_t*)ltoh(buffer, 4); + + fseek(fp, 2, SEEK_CUR); + fread(buffer, 1, 2, fp); + out->bitpp = *(uint16_t*)ltoh(buffer, 2); + out->bytepp = out->bitpp / 8; + + if(out->bitpp != 24 && out->bitpp != 32) + return 0; + + strcpy(out->file, file); + return 1; +} + +bmp_t* bmp_load(const char* file) { + return bmp_load_chunk(file, 0, 0, -1, -1); +} + +bmp_t* bmp_load_chunk + (const char* file, int x, int y, int width, int height) +{ + if(x < 0 || y < 0) + return NULL; + + bmp_meta_t data; + if(!bmp_load_metadata(file, &data)) + return NULL; + + bmp_t* bmp = malloc(sizeof(bmp_t)); + bmp->pixels = NULL; + bmp->data = data; + if(!bmp_reload_chunk(bmp, x, y, width, height)) { + free(bmp); + return NULL; + } + + return bmp; +} + +int bmp_reload_chunk(bmp_t* bmp, int x, int y, int width, int height) { + bmp_meta_t* data = &bmp->data; + if(data == NULL) + return 0; + + FILE* fp = fopen(data->file, "rb"); + if(fp == NULL) + return 0; + + if(x > data->width || y > data->height) { + fclose(fp); + return NULL; + } + + if(bmp->pixels != NULL) { + for(int i = 0; i < bmp->height; ++i) + free(bmp->pixels[i]); + free(bmp->pixels); + } + + width = (width <= 0 || (x + width > data->width)) + ? data->width - x + : width; + height = (height <= 0 || (y + height > data->height)) + ? data->height - y + : height; + + bmp->width = width; + bmp->height = height; + bmp->pixels = malloc(sizeof(pixel_t*) * height); + for(int i = 0; i < height; ++i) + bmp->pixels[i] = malloc(sizeof(pixel_t) * width); + + uint8_t buffer[4]; + for(int ay = 0; ay < height; ++ay) { + fseek(fp, + data->header_size + + (data->width * (data->height - (y + ay) - 1) * data->bytepp) + + x * data->bytepp, + SEEK_SET + ); + + for(int ax = 0; ax < width; ++ax) { + fread(buffer, 1, data->bytepp, fp); + + pixel_t* px = &bmp->pixels[ay][ax]; + px->b = buffer[0]; + px->g = buffer[1]; + px->r = buffer[2]; + } + } + + fclose(fp); + return 1; +} + +void bmp_unload(bmp_t* bmp) { + free(bmp->pixels); + free(bmp); +} \ No newline at end of file diff --git a/src/koa/file.h b/src/koa/file.h index 5212d8a..082995e 100644 --- a/src/koa/file.h +++ b/src/koa/file.h @@ -3,8 +3,10 @@ #include #include +#include #include +#include "koa/etc.h" #include "koa/thread.h" #include "koa/time.h" @@ -16,4 +18,30 @@ void err_out(const char*); char* file_read(const char*); +// BEGIN BMP LOADING FUNCTIONS + +typedef struct { + uint8_t r, g, b; +} pixel_t; + +typedef struct { + char file[4096]; + uint32_t width, height, size, + header_size, body_size; + uint16_t bitpp, bytepp; +} bmp_meta_t; + +typedef struct { + bmp_meta_t data; + + uint32_t width, height; + pixel_t** pixels; +} bmp_t; + +bmp_t* bmp_load(const char*); +bmp_t* bmp_load_chunk(const char*, int, int, int, int); +int bmp_reload_chunk(bmp_t*, int, int, int, int); +int bmp_load_metadata(const char*, bmp_meta_t*); +void bmp_unload(bmp_t*); + #endif diff --git a/src/koa/sdl.c b/src/koa/sdl.c new file mode 100644 index 0000000..fb092ac --- /dev/null +++ b/src/koa/sdl.c @@ -0,0 +1,29 @@ +#include "sdl.h" + +void get_pixel(SDL_Color* out, SDL_Surface* img, int x, int y) { + int bpp = img->format->BytesPerPixel; + uint8_t* ptr = (uint8_t*)img->pixels + y * img->pitch + x * bpp; + Uint32 pixel; + + switch(bpp) { + case 1: + pixel = *ptr; + break; + case 2: + pixel = *(Uint16*)ptr; + break; + case 3: + if(SDL_BYTEORDER == SDL_BIG_ENDIAN) + pixel = ptr[0] << 16 | ptr[1] << 8 | ptr[2]; + else + pixel = ptr[0] | ptr[1] << 8 | ptr[2] << 16; + break; + case 4: + pixel = *(Uint32*)ptr; + break; + default: + pixel = 0; + } + + SDL_GetRGBA(pixel, img->format, &out->r, &out->g, &out->b, &out->a); +} diff --git a/src/koa/sdl.h b/src/koa/sdl.h new file mode 100644 index 0000000..a6b5666 --- /dev/null +++ b/src/koa/sdl.h @@ -0,0 +1,13 @@ +#ifndef KOA_SDL_H +#define KOA_SDL_H + +#include +#include + +typedef struct { + uint8_t r, g, b, a; +} pixel_t; + +void get_pixel(SDL_Color*, SDL_Surface*, int x, int y); + +#endif diff --git a/src/main.c b/src/main.c index 3f0a6c6..4eff89f 100644 --- a/src/main.c +++ b/src/main.c @@ -1,12 +1,12 @@ #include #include #include +#include #include + #include #include -#include - #include "koa/file.h" #include "okuu/mesh.h" #include "okuu/shader.h" @@ -17,6 +17,7 @@ struct { SDL_Window* window; SDL_GLContext ctx; + const uint8_t* keys; int mode, running; mesh_t* monkey; @@ -40,7 +41,7 @@ int main(int argc, char* argv[]) { if(init() < 0) return -1; - _g.monkey = mesh_load("data/monkey.rbm"); + _g.monkey = mesh_load("data/player.rbm"); _s_def.shader = shader_create("default"); shader_source(_s_def.shader, 2, @@ -51,6 +52,7 @@ int main(int argc, char* argv[]) { "model", "view", "projection" ); + _g.keys = SDL_GetKeyboardState(NULL); _g.running = 1; while(_g.running) run(); @@ -61,22 +63,13 @@ int main(int argc, char* argv[]) { void run() { static mat4 model, view, projection; + static float rot_up = 45, rot_around = 45; static int init = 1; if(init) { - //glm_translate_make(model, (vec3){ 0.0f, 0.f, -3.f }); - //glm_rotate(model, glm_rad(180), (vec3){0.f, 1.f, 0.f}); - glm_rotate_make(model, glm_rad(180), (vec3){ 0.f, 1.f, 0.f }); - //glm_mat4_identity(model); + glm_rotate_make(model, glm_rad(90), (vec3){ 0.f, -1.f, 0.f }); - //glm_mat4_identity(view); - - glm_lookat( - (vec3){3.f, 3.f, 3.f}, - (vec3){0.f, 0.f, 0.f}, - (vec3){0.f, 1.f, 0.f}, - view - ); + glm_mat4_identity(view); glm_perspective( glm_rad(45), @@ -85,11 +78,6 @@ void run() { projection ); - /*glm_perspective_default( - (float)WINDOW_WIDTH/(float)WINDOW_HEIGHT, - projection - );*/ - shader_start(_s_def.shader); { glUniformMatrix4fv(_ATTR(DEF_MODEL), 1, GL_FALSE, (float*)model); glUniformMatrix4fv(_ATTR(DEF_VIEW), 1, GL_FALSE, (float*)view); @@ -103,7 +91,21 @@ void run() { glClearColor(0.f, 0.f, 0.5f, 0.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + float radius = 2.f + 2.f * (rot_up / 90.f); + glm_lookat( + (vec3){ + cos(glm_rad(rot_up)) * radius * cos(glm_rad(rot_around)), + radius * sin(glm_rad(rot_up)), + cos(glm_rad(rot_up)) * radius * sin(glm_rad(rot_around)) + }, + (vec3){0.f, 0.f, 0.f}, + (vec3){0.f, 1.f, 0.f}, + view + ); + shader_start(_s_def.shader); { + glUniformMatrix4fv(_ATTR(DEF_VIEW), 1, GL_FALSE, (float*)view); + mesh_bind(_g.monkey); mesh_render(_g.monkey); mesh_unbind(); @@ -111,26 +113,34 @@ void run() { SDL_GL_SwapWindow(_g.window); + SDL_PumpEvents(); + + if(_g.keys[SDL_SCANCODE_ESCAPE]) + _g.running = 0; + if(_g.keys[SDL_SCANCODE_F]) { + _g.mode = !_g.mode; + SDL_SetWindowFullscreen( + _g.window, + _g.mode == 0 + ? 0 + : SDL_WINDOW_FULLSCREEN + ); + } + + if(_g.keys[SDL_SCANCODE_UP]) + rot_up = glm_min(89.f, rot_up + 1.5f); + else if(_g.keys[SDL_SCANCODE_DOWN]) + rot_up = glm_max(0.f, rot_up - 1.5f); + + if(_g.keys[SDL_SCANCODE_RIGHT]) + rot_around -= 2.f; + else if(_g.keys[SDL_SCANCODE_LEFT]) + rot_around += 2.f; + SDL_Event ev; while(SDL_PollEvent(&ev)) { - if(ev.type == SDL_KEYDOWN) { - switch(ev.key.keysym.sym) { - case SDLK_ESCAPE: - _g.running = 0; - break; - case 'f': - _g.mode = !_g.mode; - SDL_SetWindowFullscreen( - _g.window, - _g.mode == 0 - ? 0 - : SDL_WINDOW_FULLSCREEN - ); - break; - } - } else if(ev.type == SDL_QUIT) { + if(ev.type == SDL_QUIT) _g.running = 0; - } } } diff --git a/src/okuu/mesh.c b/src/okuu/mesh.c index 9322cbc..cd8f929 100644 --- a/src/okuu/mesh.c +++ b/src/okuu/mesh.c @@ -8,24 +8,6 @@ typedef struct { uint32_t data[3][3]; } _tri_t; -uint8_t* _ord(uint8_t* buf, int length) { - static int end_chk = -1; - if(end_chk == -1) { - uint16_t chk = 0xB00B; - end_chk = ((uint8_t*)&chk)[0] == 0x0B; - } - - if(end_chk) - return buf; - - uint8_t tmp[8] = { 0 }; - for(int i = 0; i < length; ++i) - tmp[i] = buf[length - i - 1]; - memcpy(buf, tmp, length); - - return buf; -} - int _populate_pts (_pt_t* data, FILE* fp, uint32_t length, int width) { @@ -38,7 +20,7 @@ int _populate_pts if(chk != 4) return 0; - data[i].data[j] = *(float*)_ord(buffer, 4); + data[i].data[j] = *(float*)ltoh(buffer, 4); } } @@ -60,7 +42,7 @@ int _populate_faces if(chk != length) return 0; - data[at].data[i][j] = *(uint32_t *) _ord(buffer, 4); + data[at].data[i][j] = *(uint32_t *) ltoh(buffer, 4); } } @@ -86,7 +68,7 @@ mesh_t* mesh_load(const char* file) { for(int i = 0; i < 4; ++i) { fread(buffer, 1, 4, fp); - counts[i] = *(uint32_t*)_ord(buffer, 4); + counts[i] = *(uint32_t*)ltoh(buffer, 4); } if(feof(fp) || counts[VERT_CNT] == 0 || counts[FACE_CNT] == 0) { diff --git a/src/okuu/terrain.c b/src/okuu/terrain.c new file mode 100644 index 0000000..3230700 --- /dev/null +++ b/src/okuu/terrain.c @@ -0,0 +1,8 @@ +#include "terrain.h" + +terrain_t* terrain_load + (const char* heights, const char* colors, + int initial_x, int initial_y) +{ + +} \ No newline at end of file diff --git a/src/okuu/terrain.h b/src/okuu/terrain.h new file mode 100644 index 0000000..21a5a88 --- /dev/null +++ b/src/okuu/terrain.h @@ -0,0 +1,29 @@ +#ifndef OKUU_TERRAIN_H +#define OKUU_TERRAIN_H + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "koa/file.h" + +#define CHUNK_SIZE 20 + +typedef struct { + bmp_meta_t meta[2]; + GLuint buffers[3], vao; + int offset_x, offset_y; + uint8_t heights[CHUNK_SIZE][CHUNK_SIZE]; +} terrain_t; + +terrain_t* terrain_load(const char*, const char*, int, int); + +void terrain_unload(terrain_t*); + +#endif