diff --git a/bin/back b/bin/back index 3d7bfca..c552269 100755 Binary files a/bin/back and b/bin/back differ diff --git a/src/base.c b/src/base.c index aba5b62..f71bf5f 100644 --- a/src/base.c +++ b/src/base.c @@ -209,6 +209,96 @@ void pop(array* arr, int elt) { } } +bool str_equal(char* s1, char* s2) { + if(s1[0] == '\0' || s2[0] == '\0') { + return (s1[0] == '\0' && s2[0] == '\0'); + } + return (s1[0] == s2[0] && str_equal(&s1[1], &s2[1])); +} + +// ------------------------------------------------------------------------------------------------ // + +void linked_add(linkedList* lst, int x, int y, char* flag) { + if(lst == NULL) { + fprintf(stderr, "ERROR : linked list has not been initialized\n"); + exit(1); + } else if(lst->next == NULL) { + lst->next = malloc(sizeof(linkedList)); + lst->next->coord = x + 16*y ; + lst->next->flag = flag ; + lst->next->next = NULL ; + } else { + linked_add(lst->next, x, y, flag); + } +} + +void linked_removeCoord(linkedList* lst, int x, int y) { + if(lst != NULL) { + if(lst->coord == x + 16*y) { + linkedList* temp = lst->next ; + free(lst) ; + lst = temp ; + } else { + linked_removeCoord(lst->next, x, y); + } + } +} + +void linked_removeFlag(linkedList* lst, char* flag) { + if(lst != NULL) { + if(lst->flag == flag) { + linkedList* temp = lst->next ; + free(lst) ; + lst = temp ; + } else { + linked_removeFlag(lst->next, flag); + } + } +} + +void linked_change(linkedList* lst, int x, int y, char* flag) { + linked_removeCoord(lst, x, y); + linked_add(lst, x, y, flag); +} + +bool linked_mem(linkedList* lst, int x, int y, char** flag) { + if(lst == NULL) { + return false; + } + //printf("Searching for (%d, %d) [%d] ; have [%d]\n", x, y, x + 16*y, lst->coord); + if(lst->coord == x + 16*y) { + *flag = lst->flag; + return true ; + } + return linked_mem(lst->next, x, y, flag); +} + +linkedList* linked_copy(linkedList* src) { + linkedList* new = malloc(sizeof(linkedList)) ; + new->flag = "E" ; + new->coord = 0 ; + new->next = NULL ; + + //printf("in\n"); + linkedList* curSrc = src->next ; + //printf("out\n"); + + while(curSrc != NULL) { + //printf("cp\n"); + linked_add(new, curSrc->coord%8, curSrc->coord/16, curSrc->flag); + curSrc = curSrc->next; + } + + return new ; +} + +void linkedPrint(linkedList* lst) { + if(lst != NULL) { + printf("[(%d, %d), %s] ", lst->coord%8, lst->coord/16, lst->flag); + linkedPrint(lst->next); + } +} + // ------------------------------------------------------------------------------------------------ // void import_digits(SDL_Renderer* renderer) { diff --git a/src/base.h b/src/base.h index c693eb7..7235e8e 100644 --- a/src/base.h +++ b/src/base.h @@ -47,6 +47,22 @@ void append(array* arr, int elt); void pop(array* arr, int elt); +bool str_equal(char* s1, char* s2); + +void linked_add(linkedList* lst, int x, int y, char* flag); + +void linked_removeCoord(linkedList* lst, int x, int y); + +void linked_removeFlag(linkedList* lst, char* flag); + +void linked_change(linkedList* lst, int x, int y, char* flag); + +bool linked_mem(linkedList* lst, int x, int y, char** flag); + +linkedList* linked_copy(linkedList* src); + +void linkedPrint(linkedList* lst); + void import_digits(SDL_Renderer* renderer); void import_letters(SDL_Renderer* renderer); diff --git a/src/display.c b/src/display.c index 8b8fc32..19daf13 100644 --- a/src/display.c +++ b/src/display.c @@ -136,6 +136,22 @@ void drawStringToRenderer(SDL_Renderer* renderer, imgs data, char* s, int X, int } } +void linked_draw(SDL_Renderer* renderer, linkedList* lst, int chx, int chy, int xmin, int xmax, int ymin, int ymax) { + if(lst != NULL) { + int cux = 50*(8*chx + lst->coord/16); + int cuy = 50*(8*chy + lst->coord%8); + int cux2 = 50*(8*chx + lst->coord/16+1); + int cuy2 = 50*(8*chy + lst->coord%8+1); + int nxmin = to_int((to_double(cux) - to_double(xmin)) * to_double(__width__)) / (to_double(xmax) - to_double(xmin)) ; + int nymin = to_int((to_double(cuy) - to_double(ymin)) * to_double(__height__)) / (to_double(ymax) - to_double(ymin)) ; + int nxmin2 = to_int((to_double(cux2) - to_double(xmin)) * to_double(__width__)) / (to_double(xmax) - to_double(xmin)) ; + int nymin2 = to_int((to_double(cuy2) - to_double(ymin)) * to_double(__height__)) / (to_double(ymax) - to_double(ymin)) ; + placeRectToRenderer(renderer, nxmin, nymin, nxmin2 - nxmin, nymin2 - nymin, 32+96*(str_equal(lst->flag, "spinCC")), 255, 32+96*(str_equal(lst->flag, "spinCW")), SDL_ALPHA_OPAQUE/2); + + linked_draw(renderer, lst->next, chx, chy, xmin, xmax, ymin, ymax); + } +} + void drawChunkToRenderer(SDL_Renderer* renderer, chunk* ch, int xmin, int xmax, int ymin, int ymax) { if(ch->draw_id != draw_par) { ch->draw_id = draw_par ; @@ -155,6 +171,7 @@ void drawChunkToRenderer(SDL_Renderer* renderer, chunk* ch, int xmin, int xmax, cur = cur / 2 ; } } + linked_draw(renderer, ch->chdata.meta->next, ch->chx, ch->chy, xmin, xmax, ymin, ymax); } } // branchless goes brrr diff --git a/src/display.h b/src/display.h index 12da5c4..dad2607 100644 --- a/src/display.h +++ b/src/display.h @@ -21,6 +21,8 @@ void drawNumberToRenderer(SDL_Renderer* renderer, imgs data, int n, int X, int Y void drawStringToRenderer(SDL_Renderer* renderer, imgs data, char* s, int X, int Y, int W, int H); +void linked_draw(SDL_Renderer* renderer, linkedList* lst, int chx, int chy, int xmin, int xmax, int ymin, int ymax); + void drawChunkToRenderer(SDL_Renderer* renderer, chunk* ch, int xmin, int xmax, int ymin, int ymax); void drawHashToRenderer(SDL_Renderer* renderer, int chx, int chy, int xmin, int xmax, int ymin, int ymax, int distx, int disty); diff --git a/src/generation.c b/src/generation.c index 822313b..4330a4b 100644 --- a/src/generation.c +++ b/src/generation.c @@ -47,6 +47,8 @@ imgs letters ; template full ; template empty ; +linkedList* endLst ; + // yes Valentin I learned to use .h the intended way xD // ------------------------------------------------------------------------ // @@ -61,6 +63,7 @@ template copy(template src) { new.eastsig = src.eastsig; new.westsig = src.westsig; new.checkCompat = src.checkCompat ; + new.meta = linked_copy(src.meta); new.lines = malloc(sizeof(uint8_t)*8); for(int i = 0; i < 8; i++) { new.lines[i] = src.lines[i]; @@ -108,7 +111,16 @@ void print_template(int config_id) { printf("\n"); } -void rotateTemplateClockWise(int config_id) { +void rotateLinkedListCounterClockWise(linkedList* lst) { + if(lst != NULL) { + uint8_t newc = (lst->coord/16) + 16 * (7- (lst->coord%8)); + //printf("(%d, %d) -> (%d, %d)\n", lst->coord%8, lst->coord/16, newc%8, newc/16); + lst->coord = newc ; + rotateLinkedListCounterClockWise(lst->next); + } +} + +void rotateTemplateCounterClockWise(int config_id) { // 1st line become last column ... last line become 1st column uint8_t* new = malloc(sizeof(uint8_t)*8); @@ -128,9 +140,37 @@ void rotateTemplateClockWise(int config_id) { } }; - if(config_id >= 9 ) { - //print_template(config_id); + rotateLinkedListCounterClockWise(configs[config_id].meta); + + free(new); +} + +void rotateChunkCounterClockWise(int chx, int chy) { + chunk* ch = gridGet(map, chx, chy); + if(ch == NULL) { + fprintf(stderr, "ERROR : cannot rotate non-existing chunk\n"); + exit(1); } + // 1st line become last column ... last line become 1st column + uint8_t* new = malloc(sizeof(uint8_t)*8); + + ch->chdata.westsig = ch->chdata.lines[7]; + ch->chdata.eastsig = ch->chdata.lines[0]; + + for(int i = 0; i < 8; i++) { + new[i] = ch->chdata.lines[i]; + ch->chdata.lines[i] = 0; + }; + for(int i = 0; i < 8; i++) { + uint8_t rem = new[i]; + for(int j = 0; j < 8; j++) { + ch->chdata.lines[j] *= 2 ; + ch->chdata.lines[j] += rem%2 ; + rem = rem / 2 ; + } + }; + + rotateLinkedListCounterClockWise(ch->chdata.meta); free(new); } @@ -180,7 +220,7 @@ bool is_compat_with_spins(int cx, int cy, int idx) { if(is_compat_sig_north(cx, cy, idx) && is_compat_sig_east(cx, cy, idx) && is_compat_sig_south(cx, cy, idx) && is_compat_sig_west(cx, cy, idx)) { return true ; } else { - rotateTemplateClockWise(idx); + rotateTemplateCounterClockWise(idx); } }; return false; @@ -190,7 +230,7 @@ bool is_compat_with_spins_uno(int cx, int cy, int idx) { if(is_compat_sig_north(cx, cy, idx) && is_compat_sig_east(cx, cy, idx) && is_compat_sig_south(cx, cy, idx) && is_compat_sig_west(cx, cy, idx)) { return true ; } else { - rotateTemplateClockWise(idx); + rotateTemplateCounterClockWise(idx); return false; } } @@ -209,7 +249,7 @@ void generate_chunk_all(int cx, int cy) { if(is_compat_with_spins_uno(cx, cy, idx)) { i -= 1; if(i != 0) { - rotateTemplateClockWise(idx); + rotateTemplateCounterClockWise(idx); if(k == 3) { idx = (idx+1)%n_configs; k = 0 ; @@ -268,6 +308,11 @@ void initialize(SDL_Renderer* renderer) { full.westsig = 255 ; full.eastsig = 255 ; + full.meta = malloc(sizeof(linkedList)) ; + full.meta->flag = "E" ; + full.meta->coord = 0 ; + full.meta->next = NULL ; + full.checkCompat = false ; for(int i = 0; i < 8; i++) { @@ -292,6 +337,16 @@ void initialize(SDL_Renderer* renderer) { empty.id = -1 ; + empty.meta = malloc(sizeof(linkedList)) ; + empty.meta->flag = "E" ; + empty.meta->coord = 0 ; + empty.meta->next = NULL ; + + endLst = malloc(sizeof(linkedList)); + endLst->flag = "E"; + endLst->coord = 0 ; + endLst->next = NULL ; + generate_chunk(0, 0, 2); } @@ -310,15 +365,19 @@ void parse_one(FILE* ptr, FILE* ptr2, int index) { for(int j = 0; j < 8; j++) { int xres = get_integer_plus_align(ptr, ptr2); configs[index].lines[i] *= 2 ; - configs[index].lines[i] += xres ; + configs[index].lines[i] += (xres > 0) ; + + if(xres == 2) { + printf("[%d] SP+1 : %d, %d\n", index, i, 7-j); + linked_add(configs[index].meta, i, 7-j, "spinCC"); + } else if(xres == 3) { + printf("[%d] SP+1 : %d, %d\n", index, i, 7-j); + linked_add(configs[index].meta, i, 7-j, "spinCW"); + } if(j == 7) { - //configs[index].westsig *= 2; - //configs[index].westsig += xres; configs[index].westsig += pw(2, i) * xres ; } else if(j == 0) { - //configs[index].eastsig *= 2; - //configs[index].eastsig += xres; configs[index].eastsig += pw(2, i) * xres ; } } @@ -330,7 +389,9 @@ void parse_one(FILE* ptr, FILE* ptr2, int index) { printf("-----| Template %d (line %d) |-----\n", index, 9*index); print_template(index); printf("sigs : (%d, %d, %d, %d) (N, E, S, W)\n", configs[index].lines[0], configs[index].eastsig, configs[index].lines[7], configs[index].westsig); - printf("\n"); + printf("SP : "); + linkedPrint(configs[index].meta); + printf("\n-----------------------------------\n"); } void parse_configs(char* filename, int n_conf) { @@ -345,6 +406,12 @@ void parse_configs(char* filename, int n_conf) { configs[i].eastsig = 0 ; configs[i].westsig = 0 ; configs[i].checkCompat = doCheck ; + + configs[i].meta = malloc(sizeof(linkedList)) ; + configs[i].meta->flag = "E" ; + configs[i].meta->coord = 0 ; + configs[i].meta->next = NULL ; + configs[i].lines = malloc(sizeof(uint8_t)*8); for(int j = 0; j < 8; j++) { configs[i].lines[j] = 0; diff --git a/src/generation.h b/src/generation.h index 3e0bcb6..3b2a97d 100644 --- a/src/generation.h +++ b/src/generation.h @@ -9,7 +9,9 @@ void generate_chunk_raw(int x, int y, template tpl); void print_template(int config_id); -void rotateTemplateClockWise(int config_id); +void rotateTemplateCounterClockWise(int config_id); + +void rotateChunkCounterClockWise(int chx, int chy); void signature(template t); diff --git a/src/hash.h b/src/hash.h index 910202d..a65f79b 100644 --- a/src/hash.h +++ b/src/hash.h @@ -4,6 +4,14 @@ #define GRID_H #include +typedef enum special {ROT_CC, ROT_CW} special ; + +typedef struct linkedList { + uint8_t coord ; // coord%8 = x ; coord/16 = y + char* flag ; + struct linkedList* next ; +} linkedList ; + typedef struct template { uint8_t id ; uint8_t* lines ; // len = 8 @@ -12,6 +20,8 @@ typedef struct template { uint8_t eastsig ; uint8_t westsig ; + + linkedList* meta ; } template ; typedef struct chunk { diff --git a/src/move.c b/src/move.c index b956f2e..bb87546 100644 --- a/src/move.c +++ b/src/move.c @@ -19,17 +19,61 @@ #include "move.h" double speed = 0.5 ; -int precision = 12 ; +int precision = 8 ; double εx = 0.0; double εy = 0.0; +bool useSpecialTiles(int chx, int chy, int x, int y) { + chunk* ch = gridGet(map, chx, chy); + if(ch == NULL) { + fprintf(stderr, "ERROR : action performed in unloaded chunk\n"); + exit(1); + } + //linkedPrint(ch->chdata.meta->next); + //printf("\n"); + char* flag ; + if(linked_mem(ch->chdata.meta->next, y, x, &flag)) { + //printf("Triggered\n"); + if(str_equal(flag, "spinCC")) { + rotateChunkCounterClockWise(chx, chy); + double plx = (double)(player_x + εx) ; + double ply = (double)(player_y + εy) ; + + double npx = 7.99999999 - ply ; + double npy = plx ; + //printf("(%lf, %lf) -> (%lf, %lf)\n", plx, ply, npx, npy); + player_x = (int)npx ; + εx = (double)(npx - (int)npx) ; + + player_y = (int)npy ; + εy = (double)(npy - (int)npy) ; + } else if(str_equal(flag, "spinCW")) { + for(int k = 0; k < 3; k++) { + rotateChunkCounterClockWise(chx, chy); + double plx = (double)(player_x + εx) ; + double ply = (double)(player_y + εy) ; + + double npx = 7.99999999 - ply ; + double npy = plx ; + //printf("(%lf, %lf) -> (%lf, %lf)\n", plx, ply, npx, npy); + player_x = (int)npx ; + εx = (double)(npx - (int)npx) ; + + player_y = (int)npy ; + εy = (double)(npy - (int)npy) ; + } + } + } + return true ; +} + bool checkCollision() { return (unpack_coord(gridGet(map, player_cx, player_cy)->chdata.lines, player_x, player_y)); } bool checkCollision2(int cx, int cy, int x, int y) { - return (unpack_coord(gridGet(map, cx, cy)->chdata.lines, x, y)); + return (unpack_coord(gridGet(map, cx, cy)->chdata.lines, x, y) && useSpecialTiles(cx, cy, x, y)); } void normalize(int* ch_coord, int* coord, double* ε) { @@ -50,35 +94,6 @@ void normalize(int* ch_coord, int* coord, double* ε) { } } -bool checkCollisionSquare(double square_size) { - double εxmin = εx - square_size; - double εxmax = εx + square_size; - double εymin = εy - square_size; - double εymax = εy + square_size; - - int xmin = player_x ; - int xmax = player_x ; - int ymin = player_y ; - int ymax = player_y ; - - int cxmin = player_cx ; - int cxmax = player_cx ; - int cymin = player_cy ; - int cymax = player_cy ; - - normalize(&cxmin, &xmin, &εxmin); - normalize(&cxmax, &xmax, &εxmax); - normalize(&cymin, &ymin, &εymin); - normalize(&cymax, &ymax, &εymax); - - return ( - checkCollision2(cxmin, cymin, xmin, ymin) || - checkCollision2(cxmin, cymax, xmin, ymax) || - checkCollision2(cxmax, cymin, xmax, ymin) || - checkCollision2(cxmax, cymax, xmax, ymax) - ); -} - void increment_x(double dx) { εx = εx + dx ; if(εx >= 1.0) { @@ -117,10 +132,39 @@ void increment_y(double dy) { } } +bool checkCollisionSquare(double square_size) { + double εxmin = εx - square_size; + double εxmax = εx + square_size; + double εymin = εy - square_size; + double εymax = εy + square_size; + + int xmin = player_x ; + int xmax = player_x ; + int ymin = player_y ; + int ymax = player_y ; + + int cxmin = player_cx ; + int cxmax = player_cx ; + int cymin = player_cy ; + int cymax = player_cy ; + + normalize(&cxmin, &xmin, &εxmin); + normalize(&cxmax, &xmax, &εxmax); + normalize(&cymin, &ymin, &εymin); + normalize(&cymax, &ymax, &εymax); + + return ( + checkCollision2(cxmin, cymin, xmin, ymin) || + checkCollision2(cxmin, cymax, xmin, ymax) || + checkCollision2(cxmax, cymin, xmax, ymin) || + checkCollision2(cxmax, cymax, xmax, ymax) + ); +} + bool moveRequest(double dx, double dy) { increment_x(dx); increment_y(dy); - if(checkCollisionSquare(0.15)) { + if(checkCollisionSquare(0.1)) { increment_x(-dx); increment_y(-dy); return false; @@ -181,7 +225,9 @@ void moveFunctionMaster(SDL_Renderer* renderer) { drawNumberToRenderer(renderer, digits, player_cx, 10, 10, 50, 70, 0); drawNumberToRenderer(renderer, digits, player_cy, 10, 80, 50, 70, 0); drawNumberToRenderer(renderer, digits, player_x, __width__ / 3, 10, 50, 70, 0); + drawCharToRenderer(renderer, letters, 'x', __width__ / 3 -20, 10, 50, 70); drawNumberToRenderer(renderer, digits, player_y, __width__ / 3, 80, 50, 70, 0); + drawCharToRenderer(renderer, letters, 'y', __width__ / 3 -20, 80, 50, 70); drawNumberToRenderer(renderer, digits, to_int(εx*100), 2 * __width__ / 3, 10, 50, 70, 0); drawNumberToRenderer(renderer, digits, to_int(εy*100), 2 * __width__ / 3, 80, 50, 70, 0); updateRenderer(renderer); diff --git a/src/move.h b/src/move.h index 0887dcd..1422171 100644 --- a/src/move.h +++ b/src/move.h @@ -1,18 +1,20 @@ #ifndef BACK_MOVE_H #define BACK_MOVE_H +bool useSpecialTiles(int chx, int chy, int x, int y); + bool checkCollision(); bool checkCollision2(int cx, int cy, int x, int y); void normalize(int* ch_coord, int* coord, double* ε); -bool checkCollisionSquare(double square_size); - void increment_x(double dx); void increment_y(double dy); +bool checkCollisionSquare(double square_size); + bool moveRequest(double dx, double dy); void moveControl(bool* halt); diff --git a/src/structure.h b/src/structure.h index 05bfae3..481cef9 100644 --- a/src/structure.h +++ b/src/structure.h @@ -17,6 +17,8 @@ extern Grid map ; extern bool doCheck ; +extern linkedList* endLst ; + extern int emptyChance ; extern int sizeIncreaseChance ; diff --git a/templates_lv1.txt b/templates_lv1.txt index 58cb933..5d3834b 100644 --- a/templates_lv1.txt +++ b/templates_lv1.txt @@ -91,8 +91,8 @@ 1 1 0 0 0 0 1 1 1 0 0 0 0 1 1 1 0 0 0 0 1 1 1 0 -0 0 0 1 1 1 0 0 -0 0 1 1 1 0 0 0 +0 0 0 1 1 2 0 0 +0 0 3 1 1 0 0 0 0 1 1 1 0 0 0 0 1 1 1 0 0 0 0 1 1 1 0 0 0 0 1 1 @@ -100,8 +100,8 @@ 1 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 0 0 0 0 1 1 1 0 -0 0 0 1 1 1 0 0 -0 0 1 1 1 0 0 0 +0 0 0 1 1 2 0 0 +0 0 3 1 1 0 0 0 0 1 1 1 0 0 0 0 1 1 1 0 0 0 0 1 1 1 0 0 0 0 1 1 @@ -109,8 +109,8 @@ 1 1 0 0 0 0 1 1 1 0 0 0 0 1 1 1 0 0 0 0 1 1 1 1 -0 0 0 1 1 1 0 1 -0 0 1 1 1 0 0 1 +0 0 0 1 1 2 0 1 +0 0 3 1 1 0 0 1 0 1 1 1 0 0 0 1 1 1 1 0 0 0 0 1 1 1 0 0 0 0 1 1