Browse Source

Add walking up graphics. Add vc_vector. Make objects OOP

Nathaniel van Diepen 3 years ago
parent
commit
205ea30fcc
11 changed files with 558 additions and 36 deletions
  1. 1 1
      makefile
  2. BIN
      src/gfx/bm19.png
  3. BIN
      src/gfx/bm20.png
  4. BIN
      src/gfx/bm21.png
  5. BIN
      src/gfx/bm22.png
  6. 12 4
      src/gfx/convimg.yaml
  7. 332 0
      src/lib/vc_vector.c
  8. 129 0
      src/lib/vc_vector.h
  9. 42 31
      src/main.c
  10. 19 0
      src/object.c
  11. 23 0
      src/object.h

+ 1 - 1
makefile

@@ -27,5 +27,5 @@ bin/clibs.8xg:
 		 https://github.com/CE-Programming/libraries/releases/download/v8.8/clibs.8xg \
 		 -O bin/clibs.8xg
 
-emulator: bin/${NAME}.8xp bin/clibs.8xg
+emulator: debug bin/clibs.8xg
 	CEmu -a bin/clibs.8xg -s bin/${NAME}.8xp --launch ${NAME}

BIN
src/gfx/bm19.png


BIN
src/gfx/bm20.png


BIN
src/gfx/bm21.png


BIN
src/gfx/bm22.png


+ 12 - 4
src/gfx/convimg.yaml

@@ -16,13 +16,13 @@ convert: main_images             : Convert images section
     - bm1.png
     # Standing back
     - bm2.png
-    # Walking 1 front
+    # Forward 1 front
     - bm3.png
-    # Walking 1 back
+    # Forward 1 back
     - bm4.png
-    # Walking 2 front
+    # Forward 2 front
     - bm5.png
-    # Walking 2 back
+    # Forward 2 back
     - bm6.png
     # Left 1 front
     - bm7.png
@@ -48,3 +48,11 @@ convert: main_images             : Convert images section
     - bm17.png
     # Climb 2 back
     - bm18.png
+    # Backward 1 front
+    - bm19.png
+    # Backward 1 back
+    - bm20.png
+    # Backward 2 front
+    - bm21.png
+    # Backward 2 back
+    - bm22.png

+ 332 - 0
src/lib/vc_vector.c

@@ -0,0 +1,332 @@
+// https://github.com/skogorev/vc_vector
+#include "vc_vector.h"
+#include <stdlib.h>
+#include <string.h>
+
+#define GROWTH_FACTOR 1.5
+#define DEFAULT_COUNT_OF_ELEMENTS 8
+#define MINIMUM_COUNT_OF_ELEMENTS 2
+
+// ----------------------------------------------------------------------------
+
+// vc_vector structure
+
+// struct vc_vector {
+//   size_t count;
+//   size_t element_size;
+//   size_t reserved_size;
+//   char* data;
+//   vc_vector_deleter* deleter;
+// };
+
+// ----------------------------------------------------------------------------
+
+// Auxiliary methods
+
+bool vc_vector_realloc(vc_vector* vector, size_t new_count) {
+  const size_t new_size = new_count * vector->element_size;
+  char* new_data = (char*)realloc(vector->data, new_size);
+  if (!new_data) {
+    return false;
+  }
+
+  vector->reserved_size = new_size;
+  vector->data = new_data;
+  return true;
+}
+
+// [first_index, last_index)
+void vc_vector_call_deleter(vc_vector* vector, size_t first_index, size_t last_index) {
+  size_t i;
+  for (i = first_index; i < last_index; ++i) {
+    vector->deleter(vc_vector_at(vector, i));
+  }
+}
+
+void vc_vector_call_deleter_all(vc_vector* vector) {
+  vc_vector_call_deleter(vector, 0, vc_vector_count(vector));
+}
+
+// ----------------------------------------------------------------------------
+
+// Control
+
+vc_vector* vc_vector_create(size_t count_elements, size_t size_of_element, vc_vector_deleter* deleter) {
+  vc_vector* v = (vc_vector*)malloc(sizeof(vc_vector));
+  if (v != NULL) {
+    v->data = NULL;
+    v->count = 0;
+    v->element_size = size_of_element;
+    v->deleter = deleter;
+
+    if (count_elements < MINIMUM_COUNT_OF_ELEMENTS) {
+      count_elements = DEFAULT_COUNT_OF_ELEMENTS;
+    }
+
+    if (size_of_element < 1 ||
+                 !vc_vector_realloc(v, count_elements)) {
+      free(v);
+      v = NULL;
+    }
+  }
+
+  return v;
+}
+
+vc_vector* vc_vector_create_copy(const vc_vector* vector) {
+  vc_vector* new_vector = vc_vector_create(vector->reserved_size / vector->count,
+                                           vector->element_size,
+                                           vector->deleter);
+  if (!new_vector) {
+    return new_vector;
+  }
+
+  if (memcpy(vector->data,
+                      new_vector->data,
+                      new_vector->element_size * vector->count) == NULL) {
+    vc_vector_release(new_vector);
+    new_vector = NULL;
+    return new_vector;
+  }
+
+  new_vector->count = vector->count;
+  return new_vector;
+}
+
+void vc_vector_release(vc_vector* vector) {
+  if (vector->deleter != NULL) {
+    vc_vector_call_deleter_all(vector);
+  }
+
+  if (vector->reserved_size != 0) {
+    free(vector->data);
+  }
+
+  free(vector);
+}
+
+bool vc_vector_is_equals(vc_vector* vector1, vc_vector* vector2) {
+  const size_t size_vector1 = vc_vector_size(vector1);
+  if (size_vector1 != vc_vector_size(vector2)) {
+    return false;
+  }
+
+  return memcmp(vector1->data, vector2->data, size_vector1) == 0;
+}
+
+float vc_vector_get_growth_factor() {
+  return GROWTH_FACTOR;
+}
+
+size_t vc_vector_get_default_count_of_elements() {
+  return DEFAULT_COUNT_OF_ELEMENTS;
+}
+
+size_t vc_vector_struct_size() {
+  return sizeof(vc_vector);
+}
+
+// ----------------------------------------------------------------------------
+
+// Element access
+
+void* vc_vector_at(vc_vector* vector, size_t index) {
+  return vector->data + index * vector->element_size;
+}
+
+void* vc_vector_front(vc_vector* vector) {
+  return vector->data;
+}
+
+void* vc_vector_back(vc_vector* vector) {
+  return vector->data + (vector->count - 1) * vector->element_size;
+}
+
+void* vc_vector_data(vc_vector* vector) {
+  return vector->data;
+}
+
+// ----------------------------------------------------------------------------
+
+// Iterators
+
+void* vc_vector_begin(vc_vector* vector) {
+  return vector->data;
+}
+
+void* vc_vector_end(vc_vector* vector) {
+  return vector->data + vector->element_size * vector->count;
+}
+
+void* vc_vector_next(vc_vector* vector, void* i) {
+  return (char *)i + vector->element_size;
+}
+
+// ----------------------------------------------------------------------------
+
+// Capacity
+
+bool vc_vector_empty(vc_vector* vector) {
+  return vector->count == 0;
+}
+
+size_t vc_vector_count(const vc_vector* vector) {
+  return vector->count;
+}
+
+size_t vc_vector_size(const vc_vector* vector) {
+  return vector->count * vector->element_size;
+}
+
+size_t vc_vector_max_count(const vc_vector* vector) {
+  return vector->reserved_size / vector->element_size;
+}
+
+size_t vc_vector_max_size(const vc_vector* vector) {
+  return vector->reserved_size;
+}
+
+bool vc_vector_reserve_count(vc_vector* vector, size_t new_count) {
+  size_t new_size;
+  if (new_count < vector->count) {
+    return false;
+  }
+
+  new_size = vector->element_size * new_count;
+  if (new_size == vector->reserved_size) {
+    return true;
+  }
+
+  return vc_vector_realloc(vector, new_count);
+}
+
+bool vc_vector_reserve_size(vc_vector* vector, size_t new_size) {
+  return vc_vector_reserve_count(vector, new_size / vector->element_size);
+}
+
+// ----------------------------------------------------------------------------
+
+// Modifiers
+
+void vc_vector_clear(vc_vector* vector) {
+  if (vector->deleter != NULL) {
+    vc_vector_call_deleter_all(vector);
+  }
+
+  vector->count = 0;
+}
+
+bool vc_vector_insert(vc_vector* vector, size_t index, const void* value) {
+  if (vc_vector_max_count(vector) < vector->count + 1) {
+    if (!vc_vector_realloc(vector, vc_vector_max_count(vector) * GROWTH_FACTOR)) {
+      return false;
+    }
+  }
+
+  if (!memmove(vc_vector_at(vector, index + 1),
+                        vc_vector_at(vector, index),
+                        vector->element_size * (vector->count - index))) {
+
+    return false;
+  }
+
+  if (memcpy(vc_vector_at(vector, index),
+                      value,
+                      vector->element_size) == NULL) {
+    return false;
+  }
+
+  ++vector->count;
+  return true;
+}
+
+bool vc_vector_erase(vc_vector* vector, size_t index) {
+  if (vector->deleter != NULL) {
+    vector->deleter(vc_vector_at(vector, index));
+  }
+
+  if (!memmove(vc_vector_at(vector, index),
+                        vc_vector_at(vector, index + 1),
+                        vector->element_size * (vector->count - index))) {
+    return false;
+  }
+
+  vector->count--;
+  return true;
+}
+
+bool vc_vector_erase_range(vc_vector* vector, size_t first_index, size_t last_index) {
+  if (vector->deleter != NULL) {
+    vc_vector_call_deleter(vector, first_index, last_index);
+  }
+
+  if (!memmove(vc_vector_at(vector, first_index),
+                        vc_vector_at(vector, last_index),
+                        vector->element_size * (vector->count - last_index))) {
+    return false;
+  }
+
+  vector->count -= last_index - first_index;
+  return true;
+}
+
+bool vc_vector_append(vc_vector* vector, const void* values, size_t count) {
+  const size_t count_new = count + vc_vector_count(vector);
+
+  if (vc_vector_max_count(vector) < count_new) {
+    size_t max_count_to_reserved = vc_vector_max_count(vector) * GROWTH_FACTOR;
+    while (count_new > max_count_to_reserved) {
+      max_count_to_reserved *= GROWTH_FACTOR;
+    }
+
+    if (!vc_vector_realloc(vector, max_count_to_reserved)) {
+      return false;
+    }
+  }
+
+  if (memcpy(vector->data + vector->count * vector->element_size,
+                      values,
+                      vector->element_size * count) == NULL) {
+    return false;
+  }
+
+  vector->count = count_new;
+  return true;
+}
+
+bool vc_vector_push_back(vc_vector* vector, const void* value) {
+  if (!vc_vector_append(vector, value, 1)) {
+    return false;
+  }
+
+  return true;
+}
+
+bool vc_vector_pop_back(vc_vector* vector) {
+  if (vector->deleter != NULL) {
+    vector->deleter(vc_vector_back(vector));
+  }
+
+  vector->count--;
+  return true;
+}
+
+bool vc_vector_replace(vc_vector* vector, size_t index, const void* value) {
+  if (vector->deleter != NULL) {
+    vector->deleter(vc_vector_at(vector, index));
+  }
+
+  return memcpy(vc_vector_at(vector, index),
+                value,
+                vector->element_size) != NULL;
+}
+
+bool vc_vector_replace_multiple(vc_vector* vector, size_t index, const void* values, size_t count) {
+  if (vector->deleter != NULL) {
+    vc_vector_call_deleter(vector, index, index + count);
+  }
+
+  return memcpy(vc_vector_at(vector, index),
+                values,
+                vector->element_size * count) != NULL;
+}

+ 129 - 0
src/lib/vc_vector.h

@@ -0,0 +1,129 @@
+// https://github.com/skogorev/vc_vector
+
+#ifndef VCVECTOR_H
+#define VCVECTOR_H
+
+#include <stdbool.h>
+#include <stdio.h>
+
+typedef void (vc_vector_deleter)(void *);
+typedef struct vc_vector {
+  size_t count;
+  size_t element_size;
+  size_t reserved_size;
+  char* data;
+  vc_vector_deleter* deleter;
+} vc_vector;
+// typedef struct vc_vector vc_vector;
+
+// ----------------------------------------------------------------------------
+// Control
+// ----------------------------------------------------------------------------
+
+// Constructs an empty vector with an reserver size for count_elements.
+vc_vector* vc_vector_create(size_t count_elements, size_t size_of_element, vc_vector_deleter* deleter);
+
+// Constructs a copy of an existing vector.
+vc_vector* vc_vector_create_copy(const vc_vector* vector);
+
+// Releases the vector.
+void vc_vector_release(vc_vector* vector);
+
+// Compares vector content
+bool vc_vector_is_equals(vc_vector* vector1, vc_vector* vector2);
+
+// Returns constant value of the vector growth factor.
+float vc_vector_get_growth_factor();
+
+// Returns constant value of the vector default count of elements.
+size_t vc_vector_get_default_count_of_elements();
+
+// Returns constant value of the vector struct size.
+size_t vc_vector_struct_size();
+
+// ----------------------------------------------------------------------------
+// Element access
+// ----------------------------------------------------------------------------
+
+// Returns the item at index position in the vector.
+void* vc_vector_at(vc_vector* vector, size_t index);
+
+// Returns the first item in the vector.
+void* vc_vector_front(vc_vector* vector);
+
+// Returns the last item in the vector.
+void* vc_vector_back(vc_vector* vector);
+
+// Returns a pointer to the data stored in the vector. The pointer can be used to access and modify the items in the vector.
+void* vc_vector_data(vc_vector* vector);
+
+// ----------------------------------------------------------------------------
+// Iterators
+// ----------------------------------------------------------------------------
+
+// Returns a pointer to the first item in the vector.
+void* vc_vector_begin(vc_vector* vector);
+
+// Returns a pointer to the imaginary item after the last item in the vector.
+void* vc_vector_end(vc_vector* vector);
+
+// Returns a pointer to the next element of vector after 'i'.
+void* vc_vector_next(vc_vector* vector, void* i);
+
+// ----------------------------------------------------------------------------
+// Capacity
+// ----------------------------------------------------------------------------
+
+// Returns true if the vector is empty; otherwise returns false.
+bool vc_vector_empty(vc_vector* vector);
+
+// Returns the number of elements in the vector.
+size_t vc_vector_count(const vc_vector* vector);
+
+// Returns the size (in bytes) of occurrences of value in the vector.
+size_t vc_vector_size(const vc_vector* vector);
+
+// Returns the maximum number of elements that the vector can hold.
+size_t vc_vector_max_count(const vc_vector* vector);
+
+// Returns the maximum size (in bytes) that the vector can hold.
+size_t vc_vector_max_size(const vc_vector* vector);
+
+// Resizes the container so that it contains n elements.
+bool vc_vector_reserve_count(vc_vector* vector, size_t new_count);
+
+// Resizes the container so that it contains new_size / element_size elements.
+bool vc_vector_reserve_size(vc_vector* vector, size_t new_size);
+
+// ----------------------------------------------------------------------------
+// Modifiers
+// ----------------------------------------------------------------------------
+
+// Removes all elements from the vector (without reallocation).
+void vc_vector_clear(vc_vector* vector);
+
+// The container is extended by inserting a new element at position.
+bool vc_vector_insert(vc_vector* vector, size_t index, const void* value);
+
+// Removes from the vector a single element by 'index'
+bool vc_vector_erase(vc_vector* vector, size_t index);
+
+// Removes from the vector a range of elements '[first_index, last_index)'.
+bool vc_vector_erase_range(vc_vector* vector, size_t first_index, size_t last_index);
+
+// Inserts multiple values at the end of the vector.
+bool vc_vector_append(vc_vector* vector, const void* values, size_t count);
+
+// Inserts value at the end of the vector.
+bool vc_vector_push_back(vc_vector* vector, const void* value);
+
+// Removes the last item in the vector.
+bool vc_vector_pop_back(vc_vector* vector);
+
+// Replace value by index in the vector.
+bool vc_vector_replace(vc_vector* vector, size_t index, const void* value);
+
+// Replace multiple values by index in the vector.
+bool vc_vector_replace_multiple(vc_vector* vector, size_t index, const void* values, size_t count);
+
+#endif // VCVECTOR_H

+ 42 - 31
src/main.c

@@ -1,27 +1,30 @@
 #include <tice.h>
 #include <graphx.h>
 #include <keypadc.h>
+#include <debug.h>
 
 #include "gfx/main_gfx.h"
-
+#include "lib/vc_vector.h"
+#include "object.h"
 
 float scale = 3.0;
 int frameskip = 10;
 
-gfx_sprite_t* sprite;
+int max_width = LCD_WIDTH;
+int max_height = LCD_HEIGHT;
 kb_key_t arrows;
-int x = 0;
-int y = 0;
 int frame = 0;
+Object* player;
 
-void draw_sprite(){
-    gfx_FillScreen(0);
-    gfx_ScaledSprite_NoClip(sprite, x, y, scale, scale);
-    gfx_BlitBuffer();
+void log(char* msg){
+    dbg_sprintf(dbgout, "[TBP] %s\n", msg);
 }
+
 int main(void){
-    int max_width = LCD_WIDTH;
-    int max_height = LCD_HEIGHT;
+    log("New Object");
+    player = new_Object(0, 0);
+    log("Get max sizes");
+
     if(bm3->height > bm5->height){
         max_height -= bm3->height * scale;
     }else{
@@ -32,62 +35,70 @@ int main(void){
     }else{
         max_width -= bm13->width * scale;
     }
+    log("Set scale");
 
+    player->scale.x = scale;
+    player->scale.y = scale;
+
+
+    log("Start graphics");
     gfx_Begin();
     gfx_SetPalette(main_palette, sizeof_main_palette, 0);
     gfx_SetDrawBuffer();
 
-    draw_sprite();
+    log("Main loop");
     do{
-        sprite = bm1;
+        player->sprite = bm1;
         kb_Scan();
         arrows = kb_Data[7];
 
         if(arrows & kb_Down){
-            if(y < max_height){
-                y++;
+            if(player->y < max_height){
+                player->y++;
                 if(frame > 2){
-                    sprite = bm3;
+                    player->sprite = bm3;
                 }else{
-                    sprite = bm5;
+                    player->sprite = bm5;
                 }
             }
         }else if(arrows & kb_Up){
-            if(y > 0){
-                y--;
+            if(player->y > 0){
+                player->y--;
                 if(frame > 2){
-                    sprite = bm15;
+                    player->sprite = bm19;
                 }else{
-                    sprite = bm17;
+                    player->sprite = bm21;
                 }
             }
         }
         if(arrows & kb_Right){
-            if(x < max_width){
-                x++;
+            if(player->x < max_width){
+                player->x++;
                 if(frame > 2){
-                    sprite = bm11;
+                    player->sprite = bm11;
                 }else{
-                    sprite = bm13;
+                    player->sprite = bm13;
                 }
             }
         }else if(arrows & kb_Left){
-            if(x > 0){
-                x--;
+            if(player->x > 0){
+                player->x--;
                 if(frame > 2){
-                    sprite = bm7;
+                    player->sprite = bm7;
                 }else{
-                    sprite = bm9;
+                    player->sprite = bm9;
                 }
             }
         }
-        draw_sprite();
+        gfx_FillScreen(0);
+        player->draw(player);
+        gfx_BlitBuffer();
         frame++;
         if(frame > frameskip){
             frame = 0;
         }
-    }while (arrows != sk_Enter);
-
+    }while (! (kb_Data[6] & kb_Clear));
+    free(player);
     gfx_End();
     return 0;
 }

+ 19 - 0
src/object.c

@@ -0,0 +1,19 @@
+#include "object.h"
+
+void Object_update(Object* self){}
+
+void Object_draw(Object* self){
+    gfx_ScaledSprite_NoClip(
+        self->sprite, self->x, self->y,
+        self->scale.x, self->scale.y);
+}
+
+Object* new_Object(int x, int y){
+    Object* self = (Object*)malloc(sizeof(Object));
+    self->x = x;
+    self->y = y;
+    self->scale.x = self->scale.y = 1;
+    self->update = &Object_update;
+    self->draw = &Object_draw;
+    return self;
+}

+ 23 - 0
src/object.h

@@ -0,0 +1,23 @@
+#ifndef OBJECT_H_
+#define OBJECT_H_
+
+#include <graphx.h>
+
+typedef struct Scale {
+    int x;
+    int y;
+} Scale;
+typedef void (*Object_func)(struct Object*);
+typedef struct Object {
+    int x;
+    int y;
+    Scale scale;
+    gfx_sprite_t* sprite;
+
+    Object_func draw;
+    Object_func update;
+} Object;
+
+Object* new_Object(int x, int y);
+
+#endif