diff --git a/.clang-format b/.clang-format index 196c51c..e35924c 100644 --- a/.clang-format +++ b/.clang-format @@ -10,3 +10,4 @@ IndentCaseBlocks: true IncludeBlocks: Regroup AllowShortBlocksOnASingleLine: Empty ColumnLimit: 80 +AllowShortEnumsOnASingleLine: false diff --git a/CMakeLists.txt b/CMakeLists.txt index e646b91..6d258ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,6 +34,7 @@ set(SOURCES src/npc.c src/events.c src/animation.c + src/inventory.c # ... ) # Shared assets, fx-9860G-only assets and fx-CG-50-only assets @@ -56,6 +57,8 @@ set(ASSETS set(ASSETS_cg assets-cg/player_male.png assets-cg/player_female.png + assets-cg/player_male_inv.png + assets-cg/player_female_inv.png assets-cg/npc/char/npc_male.png assets-cg/npc/char/npc_female.png assets-cg/npc/char/npc_milkman.png @@ -69,6 +72,10 @@ set(ASSETS_cg assets-cg/INFO_Icon.png assets-cg/player_face.png assets-cg/font.png + assets-cg/inventory.png + assets-cg/items.png + assets-cg/selection.png + assets-cg/selected.png ) set(ASSETS_cg_EGA64 @@ -83,6 +90,8 @@ set(ASSETS_fx assets-fx/SGN_Icon.png assets-fx/player_face.png assets-fx/font.png + assets-fx/selection.png + assets-fx/selected.png # ... ) @@ -98,6 +107,8 @@ set(ASSETS_fx_1b assets-fx/1b/npc/face/npc_milkman.png assets-fx/1b/npc/face/npc_police.png assets-fx/1b/INFO_Icon.png + assets-fx/1b/inventory.png + assets-fx/1b/items.png # ... ) @@ -112,7 +123,9 @@ set(ASSETS_fx_2b assets-fx/2b/npc/face/npc_female.png assets-fx/2b/npc/face/npc_milkman.png assets-fx/2b/npc/face/npc_police.png - assets-fx/1b/INFO_Icon.png + assets-fx/2b/INFO_Icon.png + assets-fx/2b/inventory.png + assets-fx/2b/items.png # ... ) diff --git a/assets-cg/base_slot.png b/assets-cg/base_slot.png new file mode 100644 index 0000000..8a45491 Binary files /dev/null and b/assets-cg/base_slot.png differ diff --git a/assets-cg/inventory.ase b/assets-cg/inventory.ase new file mode 100644 index 0000000..4e9487a Binary files /dev/null and b/assets-cg/inventory.ase differ diff --git a/assets-cg/inventory.png b/assets-cg/inventory.png new file mode 100644 index 0000000..c7030a0 Binary files /dev/null and b/assets-cg/inventory.png differ diff --git a/assets-cg/items.png b/assets-cg/items.png new file mode 100644 index 0000000..08ed2c2 Binary files /dev/null and b/assets-cg/items.png differ diff --git a/assets-cg/player_female_inv.png b/assets-cg/player_female_inv.png new file mode 100644 index 0000000..49e2bae Binary files /dev/null and b/assets-cg/player_female_inv.png differ diff --git a/assets-cg/player_male_inv.png b/assets-cg/player_male_inv.png new file mode 100644 index 0000000..0361d95 Binary files /dev/null and b/assets-cg/player_male_inv.png differ diff --git a/assets-cg/selected.png b/assets-cg/selected.png new file mode 100644 index 0000000..ae7cb57 Binary files /dev/null and b/assets-cg/selected.png differ diff --git a/assets-cg/selection.png b/assets-cg/selection.png new file mode 100644 index 0000000..5348c4c Binary files /dev/null and b/assets-cg/selection.png differ diff --git a/assets-fx/1b/fxconv-metadata.txt b/assets-fx/1b/fxconv-metadata.txt index 9f0baf7..881385f 100644 --- a/assets-fx/1b/fxconv-metadata.txt +++ b/assets-fx/1b/fxconv-metadata.txt @@ -1,3 +1,11 @@ INFO_Icon.png: type: bopti-image name: INFO_Icon_img + +inventory.png: + type: bopti-image + name: inventory_img + +items.png: + type: bopti-image + name: items_img diff --git a/assets-fx/1b/inventory.png b/assets-fx/1b/inventory.png new file mode 100644 index 0000000..53d66aa Binary files /dev/null and b/assets-fx/1b/inventory.png differ diff --git a/assets-fx/1b/items.png b/assets-fx/1b/items.png new file mode 100644 index 0000000..eeb6dbf Binary files /dev/null and b/assets-fx/1b/items.png differ diff --git a/assets-fx/2b/fxconv-metadata.txt b/assets-fx/2b/fxconv-metadata.txt index 9f0baf7..881385f 100644 --- a/assets-fx/2b/fxconv-metadata.txt +++ b/assets-fx/2b/fxconv-metadata.txt @@ -1,3 +1,11 @@ INFO_Icon.png: type: bopti-image name: INFO_Icon_img + +inventory.png: + type: bopti-image + name: inventory_img + +items.png: + type: bopti-image + name: items_img diff --git a/assets-fx/2b/inventory.png b/assets-fx/2b/inventory.png new file mode 100644 index 0000000..53d66aa Binary files /dev/null and b/assets-fx/2b/inventory.png differ diff --git a/assets-fx/2b/items.png b/assets-fx/2b/items.png new file mode 100644 index 0000000..eeb6dbf Binary files /dev/null and b/assets-fx/2b/items.png differ diff --git a/assets-fx/fxconv-metadata.txt b/assets-fx/fxconv-metadata.txt index 1d7d0f9..b3556bf 100644 --- a/assets-fx/fxconv-metadata.txt +++ b/assets-fx/fxconv-metadata.txt @@ -17,6 +17,14 @@ SGN_Icon.png: type: bopti-image name: SGN_Icon_img +selection.png: + type: bopti-image + name: selection_img + +selected.png: + type: bopti-image + name: selected_img + font.png: name: fontRPG type: font diff --git a/assets-fx/selected.png b/assets-fx/selected.png new file mode 100644 index 0000000..bd155be Binary files /dev/null and b/assets-fx/selected.png differ diff --git a/assets-fx/selection.png b/assets-fx/selection.png new file mode 100644 index 0000000..7092037 Binary files /dev/null and b/assets-fx/selection.png differ diff --git a/assets/converters.py b/assets/converters.py index b6201d9..9d3f37e 100644 --- a/assets/converters.py +++ b/assets/converters.py @@ -142,7 +142,7 @@ def convert_map(input: str, output: str, params: dict, target): indoor = int(input_map.get_property("indoor")) except Exception as e: # Show a warning - print(f"WARNING: Indoor property not found.\n") + print(f"WARNING: Indoor property not found.") if indoor: # Get the indoor tileset diff --git a/src/config.h b/src/config.h index 8410f3a..2176fa1 100644 --- a/src/config.h +++ b/src/config.h @@ -12,6 +12,9 @@ #define GRAYMODEOK 1 #endif +#define SLOT_NUM 9 +#define SLOT_COLUMNS 3 + #if GINT_RENDER_RGB /* The tile size */ #define T_HEIGHT 16 @@ -22,9 +25,15 @@ /* The size of the player */ #define P_WIDTH 16 #define P_HEIGHT 16 -/*Max number of dynamic NPCs.*/ +/* Max number of dynamic NPCs. */ #define NPC_STACK_SIZE 256 - +/* The position of the slots in the inventory */ +#define SLOT_Y 87 +#define SLOT_X_EQUIPPED 222 +#define SLOT_X 272 +#define SLOT_W 28 +#define SLOT_H 27 +#define SLOT_SPACING 32 #else /* The tile size */ #define T_HEIGHT 8 @@ -35,9 +44,15 @@ /* The player size */ #define P_WIDTH 8 #define P_HEIGHT 8 -/*Max number of "dynamic" NPCs. We are starved for static ram on fx !*/ +/* Max number of "dynamic" NPCs. We are starved for static ram on fx ! */ #define NPC_STACK_SIZE 32 - +/* The position of the slots in the inventory */ +#define SLOT_Y 24 +#define SLOT_X_EQUIPPED 72 +#define SLOT_X 88 +#define SLOT_W 8 +#define SLOT_H 8 +#define SLOT_SPACING 12 #endif /* SPEED should NOT be 8 or bigger: it may cause bugs when handling diff --git a/src/events.c b/src/events.c index 31ffdcc..79d8eb0 100644 --- a/src/events.c +++ b/src/events.c @@ -48,7 +48,7 @@ int (*_operations[OP_AMOUNT])(int, int) = {_op_null, _op_set, _op_add, _op_sub, #define MIN(a, b) a < b ? a : b -char _message_buffer[MESSAGE_BUFFER_SZ]; +char *_message_buffer; char *events_parse_string(EventHandler *handler, char *message) { size_t message_pos = 0; char in_token = 0; diff --git a/src/events.h b/src/events.h index f4a19bf..a095283 100644 --- a/src/events.h +++ b/src/events.h @@ -15,7 +15,11 @@ typedef struct { unsigned int vars; } EventHandler; -typedef enum { T_NULL, T_VAR_EDIT, T_AMOUNT } Token; +typedef enum { + T_NULL, + T_VAR_EDIT, + T_AMOUNT +} Token; typedef enum { OP_NULL, diff --git a/src/game.c b/src/game.c index 482e46c..6883b7f 100644 --- a/src/game.c +++ b/src/game.c @@ -1,6 +1,7 @@ #include "game.h" #include "config.h" +#include "inventory.h" #include "map.h" #include "mapdata.h" #include "npc.h" @@ -35,6 +36,11 @@ void game_init(Game *game) { events_init_handler(&game->handler); events_bind_variable(&game->handler, (int *)&game->player.life, "life"); events_bind_variable(&game->handler, &game->mana, "mana"); + inventory_init(&game->inventory); + /* For debugging */ + game->inventory.slots[5].i = I_GLOVE; + game->inventory.slots[1].i = I_ARMOR; + game->inventory.slots[8].i = I_TALISMAN; // reload_npc(&game); } @@ -121,8 +127,10 @@ void game_render_indicator(Game *game) { /* Draw everything. */ void game_draw(Game *game) { - /*Only clear if we are inside, the screen is guaranteed to be filled + /* Only clear if we are inside, the screen is guaranteed to be filled * otherwise */ + /* (Mibi88) if we do so, we should only use opaque tiles in the background + layer (it's currently not the case), to artefacts when rendering dialogs. */ if(game->map_level->indoor) dclear(C_WHITE); map_render_by_layer(game, BACKGROUND); @@ -135,6 +143,7 @@ void game_draw(Game *game) { dprint(8, 8, C_BLACK, "npc_count: %d", npc_count); dprint(8, 16, C_BLACK, "Mana: %d", game->mana); dprint(8, 24, C_BLACK, "X: %d Y: %d", game->player.x, game->player.y); + inventory_draw(&game->inventory, &game->player); } /* Key management */ @@ -149,98 +158,161 @@ void game_get_inputs(Game *game) { if(keydown(KEY_EXIT)) game->exittoOS = true; - /* Player actions - Prototypes in player.h and implementation in player.c */ - if(keydown(KEY_LEFT)) - player_move(game, D_LEFT); - if(keydown(KEY_RIGHT)) - player_move(game, D_RIGHT); - if(keydown(KEY_UP)) - player_move(game, D_UP); - if(keydown(KEY_DOWN)) - player_move(game, D_DOWN); - if(keydown(KEY_SHIFT)) - player_action(game); - if(keydown(KEY_OPTN)) { - game->player.is_male = !game->player.is_male; + /* Inventory */ + if(keydown(KEY_ALPHA)) { + game->inventory.open = !game->inventory.open; + /* TODO: Make something cleaner */ + while(keydown(KEY_ALPHA)) { + clearevents(); + sleep(); + } + } else if(game->inventory.open) { + if(keydown(KEY_LEFT)) + inventory_move_selection(&game->inventory, D_LEFT); + /* TODO: Make something cleaner */ + while(keydown(KEY_LEFT)) { + clearevents(); + sleep(); + } + if(keydown(KEY_RIGHT)) + inventory_move_selection(&game->inventory, D_RIGHT); + /* TODO: Make something cleaner */ + while(keydown(KEY_RIGHT)) { + clearevents(); + sleep(); + } + if(keydown(KEY_UP)) + inventory_move_selection(&game->inventory, D_UP); + /* TODO: Make something cleaner */ + while(keydown(KEY_UP)) { + clearevents(); + sleep(); + } + if(keydown(KEY_DOWN)) + inventory_move_selection(&game->inventory, D_DOWN); + /* TODO: Make something cleaner */ + while(keydown(KEY_DOWN)) { + clearevents(); + sleep(); + } + if(keydown(KEY_OPTN)) + inventory_move_from_selected(&game->inventory); /* TODO: Make something cleaner */ while(keydown(KEY_OPTN)) { clearevents(); sleep(); } - } - Player *player = &game->player; - if(keydown(KEY_SHIFT)) { - uint32_t i; - for(i = 0; i < game->map_level->nbPortal; i++) { - Portal *portal = &game->map_level->portals[i]; - if(player->x >= (int)portal->collider.x1 * PXSIZE && - player->x < (int)portal->collider.x2 * PXSIZE && - player->y >= (int)portal->collider.y1 * PXSIZE && - player->y < (int)portal->collider.y2 * PXSIZE) { - Portal *dest_portal = (Portal *)portal->portal; - Collider dest_collider = dest_portal->collider; - Map *dest_map = (Map *)portal->map; - player->x = (dest_collider.x1 + dest_collider.x2) / 2 * PXSIZE; - player->y = (dest_collider.y1 + dest_collider.y2) / 2 * PXSIZE; - game->map_level = dest_map; - /* TODO: Make something cleaner */ - while(keydown(KEY_SHIFT)) { - clearevents(); - sleep(); + if(keydown(KEY_SQUARE)) { + inventory_use(&game->inventory, &game->player); + } + if(keydown(KEY_F1)) { + inventory_unequip(&game->inventory, IT_TALISMAN); + } + if(keydown(KEY_F2)) { + inventory_unequip(&game->inventory, IT_ARMOR); + } + if(keydown(KEY_F3)) { + inventory_unequip(&game->inventory, IT_WEAPON); + } + if(keydown(KEY_SHIFT)) + game->inventory.selected = game->inventory.selection; + } else { + /* Player actions - Prototypes in player.h and implementation in + * player.c */ + if(keydown(KEY_LEFT)) + player_move(game, D_LEFT); + if(keydown(KEY_RIGHT)) + player_move(game, D_RIGHT); + if(keydown(KEY_UP)) + player_move(game, D_UP); + if(keydown(KEY_DOWN)) + player_move(game, D_DOWN); + if(keydown(KEY_SHIFT)) + player_action(game); + if(keydown(KEY_OPTN)) { + game->player.is_male = !game->player.is_male; + /* TODO: Make something cleaner */ + while(keydown(KEY_OPTN)) { + clearevents(); + sleep(); + } + } + Player *player = &game->player; + if(keydown(KEY_SHIFT)) { + uint32_t i; + for(i = 0; i < game->map_level->nbPortal; i++) { + Portal *portal = &game->map_level->portals[i]; + if(player->x >= (int)portal->collider.x1 * PXSIZE && + player->x < (int)portal->collider.x2 * PXSIZE && + player->y >= (int)portal->collider.y1 * PXSIZE && + player->y < (int)portal->collider.y2 * PXSIZE) { + Portal *dest_portal = (Portal *)portal->portal; + Collider dest_collider = dest_portal->collider; + Map *dest_map = (Map *)portal->map; + player->x = + (dest_collider.x1 + dest_collider.x2) / 2 * PXSIZE; + player->y = + (dest_collider.y1 + dest_collider.y2) / 2 * PXSIZE; + game->map_level = dest_map; + /* TODO: Make something cleaner */ + while(keydown(KEY_SHIFT)) { + clearevents(); + sleep(); + } } } } - } - /*Temp debug*/ - if(keydown(KEY_F1)) { - NPC *mynpc = npc_create(); - if(mynpc) { - mynpc->curx = (player->x << PRECISION) / PXSIZE; - mynpc->cury = (player->y << PRECISION) / PXSIZE; - mynpc->x = player->x; - mynpc->y = player->x; - mynpc->hasPath = 0; - mynpc->owns_path = false; - mynpc->face = 1; - mynpc->paused = 0; - mynpc->has_dialog = 0; - mynpc->xpath = NULL; - mynpc->ypath = NULL; + /*Temp debug*/ + if(keydown(KEY_F1)) { + NPC *mynpc = npc_create(); + if(mynpc) { + mynpc->curx = (player->x << PRECISION) / PXSIZE; + mynpc->cury = (player->y << PRECISION) / PXSIZE; + mynpc->x = player->x; + mynpc->y = player->x; + mynpc->hasPath = 0; + mynpc->owns_path = false; + mynpc->face = 1; + mynpc->paused = 0; + mynpc->has_dialog = 0; + mynpc->xpath = NULL; + mynpc->ypath = NULL; + } + while(keydown(KEY_F1)) { + clearevents(); + } } - while(keydown(KEY_F1)) { - clearevents(); + if(keydown(KEY_F2)) { + npc_remove_pos(0); + while(keydown(KEY_F2)) { + clearevents(); + } } - } - if(keydown(KEY_F2)) { - npc_remove_pos(0); - while(keydown(KEY_F2)) { - clearevents(); - } - } - /* Display Debug Information on screen */ + /* Display Debug Information on screen */ #if DEBUGMODE - if(keydown(KEY_F1)) { - game->debug_map = !game->debug_map; - } - if(keydown(KEY_F2)) { - game->debug_player = !game->debug_player; - } - if(keydown(KEY_F3)) { - game->debug_extra = !game->debug_extra; - } + if(keydown(KEY_F1)) { + game->debug_map = !game->debug_map; + } + if(keydown(KEY_F2)) { + game->debug_player = !game->debug_player; + } + if(keydown(KEY_F3)) { + game->debug_extra = !game->debug_extra; + } #endif - /* if USB is enabled - keybinding for screencapture */ + /* if USB is enabled - keybinding for screencapture */ #if USB_FEATURE - if(keydown(KEY_7)) - game->screenshot = true; - if(keydown(KEY_8)) - game->record = !game->record; + if(keydown(KEY_7)) + game->screenshot = true; + if(keydown(KEY_8)) + game->record = !game->record; #endif // USB_FEATURE + } } void game_update_animations(Game *game, unsigned char ms) { diff --git a/src/game.h b/src/game.h index f15864d..9a7f1d8 100644 --- a/src/game.h +++ b/src/game.h @@ -8,14 +8,59 @@ #include /* The direction where the player is going to. */ -typedef enum { D_UP, D_DOWN, D_LEFT, D_RIGHT } Direction; +typedef enum { + D_UP, + D_DOWN, + D_LEFT, + D_RIGHT +} Direction; -typedef enum { P_LEFTUP = -1, P_CENTER = 0, P_RIGHTDOWN = 1 } Checkpos; +typedef enum { + P_LEFTUP = -1, + P_CENTER = 0, + P_RIGHTDOWN = 1 +} Checkpos; + +typedef enum { + I_NONE, + I_ARMOR, + I_GLOVE, + I_SWORD, + I_BEER, + I_MILK, + I_TALISMAN, + I_AMOUNT +} Item; + +typedef enum { + IT_NONE, + IT_TALISMAN, + IT_ARMOR, + IT_WEAPON, + IT_FOOD, + IT_AMOUNT +} ItemType; + +typedef struct { + Item i : 4; + unsigned char durability; +} Slot; + +typedef struct { + /* Backpack slots. */ + Slot slots[SLOT_NUM]; + /* Equipped items: first slot: talisman, second slot: armor, last slot: + weapon. */ + Slot equipped[3]; + /* 1 if the inventory is open. */ + char open : 1; + char selected; + char selection; +} Inventory; typedef struct { uint32_t x1, y1; uint32_t x2, y2; - } Collider; /* Struct that define player parameters */ @@ -109,6 +154,7 @@ typedef struct { uint8_t current_group; uint8_t hostile_to_group; + /* uint16_t to keep the struct aligned */ uint16_t __padding; } NPC; @@ -178,6 +224,7 @@ typedef struct { bool debug_extra; Animation npc_animation; + Inventory inventory; int mana; /* Only for testing events TODO: Remove this! */ } Game; diff --git a/src/inventory.c b/src/inventory.c new file mode 100644 index 0000000..3533c5c --- /dev/null +++ b/src/inventory.c @@ -0,0 +1,151 @@ +#include "inventory.h" + +#include +#include + +extern bopti_image_t inventory_img; +extern bopti_image_t items_img; +extern bopti_image_t selection_img; +extern bopti_image_t selected_img; +extern bopti_image_t player_male_inv_img; +extern bopti_image_t player_female_inv_img; + +char item_types[I_AMOUNT] = {IT_NONE, IT_ARMOR, IT_WEAPON, IT_WEAPON, + IT_FOOD, IT_FOOD, IT_TALISMAN}; + +void inventory_init(Inventory *inventory) { + inventory->open = 0; + memset(inventory->slots, 0, sizeof(Slot) * SLOT_NUM); + memset(inventory->equipped, 0, sizeof(Slot) * 3); + inventory->selected = -1; + inventory->selection = 0; +} + +void inventory_draw(Inventory *inventory, Player *player) { + size_t i; + if(inventory->open) { + dimage(0, 0, &inventory_img); + for(i = 0; i < SLOT_NUM; i++) { + dsubimage(SLOT_X + (i % SLOT_COLUMNS) * SLOT_SPACING, + SLOT_Y + (i / SLOT_COLUMNS) * SLOT_SPACING, &items_img, + inventory->slots[i].i * SLOT_W, 0, SLOT_W, SLOT_H, + DIMAGE_NONE); + if(i == inventory->selection) { + dimage(SLOT_X + (i % SLOT_COLUMNS) * SLOT_SPACING, + SLOT_Y + (i / SLOT_COLUMNS) * SLOT_SPACING, + &selection_img); + } + if(i == inventory->selected) { + dimage(SLOT_X + (i % SLOT_COLUMNS) * SLOT_SPACING, + SLOT_Y + (i / SLOT_COLUMNS) * SLOT_SPACING, + &selected_img); + } + } + for(i = 0; i < 3; i++) { + dsubimage(SLOT_X_EQUIPPED, SLOT_Y + i * SLOT_SPACING, &items_img, + inventory->equipped[i].i * SLOT_W, 0, SLOT_W, SLOT_H, + DIMAGE_NONE); + } +#if GINT_RENDER_RGB + /* Render the player between the two swords if we are on cg. */ + dimage(183, 20, + player->is_male ? &player_male_inv_img : &player_female_inv_img); +#endif + } + /* TODO: Stats. */ +} + +char inventory_add(Inventory *inventory, Item item) { + size_t i; + for(i = 0; i < SLOT_NUM; i++) { + if(!inventory->slots[i].i) { + inventory->slots[i].i = item; + inventory->slots[i].durability = 255; + return 0; + } + } + return 1; +} + +void inventory_move_from_selected(Inventory *inventory) { + if(inventory->selected < 0) + return; + Slot current = inventory->slots[inventory->selection]; + Slot new = inventory->slots[inventory->selected]; + inventory->slots[inventory->selection] = new; + inventory->slots[inventory->selected] = current; +} + +void inventory_use(Inventory *inventory, Player *player) { + Item item = inventory->slots[inventory->selection].i; + switch(item_types[item]) { + case IT_TALISMAN: + inventory->equipped[0] = inventory->slots[inventory->selection]; + break; + case IT_ARMOR: + inventory->equipped[1] = inventory->slots[inventory->selection]; + break; + case IT_WEAPON: + inventory->equipped[2] = inventory->slots[inventory->selection]; + break; + case IT_FOOD: + /* TODO */ + break; + default: + break; + } + inventory->slots[inventory->selection].i = I_NONE; + inventory->slots[inventory->selection].durability = 255; +} + +void inventory_unequip(Inventory *inventory, ItemType type) { + if(inventory->slots[inventory->selection].i) + return; + switch(type) { + case IT_TALISMAN: + inventory->slots[inventory->selection] = inventory->equipped[0]; + inventory->equipped[0].i = I_NONE; + inventory->equipped[0].durability = 255; + break; + case IT_ARMOR: + inventory->slots[inventory->selection] = inventory->equipped[1]; + inventory->equipped[1].i = I_NONE; + inventory->equipped[1].durability = 255; + break; + case IT_WEAPON: + inventory->slots[inventory->selection] = inventory->equipped[2]; + inventory->equipped[2].i = I_NONE; + inventory->equipped[2].durability = 255; + break; + default: + break; + } +} + +void inventory_move_selection(Inventory *inventory, Direction direction) { + switch(direction) { + case D_UP: + inventory->selection -= SLOT_COLUMNS; + if(inventory->selection < 0) + inventory->selection = 0; + break; + case D_DOWN: + inventory->selection += SLOT_COLUMNS; + if(inventory->selection >= SLOT_NUM) { + inventory->selection = SLOT_NUM - 1; + } + break; + case D_LEFT: + if(inventory->selection > 0) { + inventory->selection--; + } + break; + case D_RIGHT: + if(inventory->selection < SLOT_NUM - 1) { + inventory->selection++; + } + break; + default: + break; + } +} diff --git a/src/inventory.h b/src/inventory.h new file mode 100644 index 0000000..5bc3116 --- /dev/null +++ b/src/inventory.h @@ -0,0 +1,15 @@ +#ifndef INVENTORY_H +#define INVENTORY_H + +/* The structs related to the inventory are defined in game.h */ +#include "game.h" + +void inventory_init(Inventory *inventory); +void inventory_draw(Inventory *inventory, Player *player); +char inventory_add(Inventory *inventory, Item item); +void inventory_move_from_selected(Inventory *inventory); +void inventory_use(Inventory *inventory, Player *player); +void inventory_unequip(Inventory *inventory, ItemType type); +void inventory_move_selection(Inventory *inventory, Direction direction); + +#endif diff --git a/src/main.c b/src/main.c index b07643d..e9762af 100644 --- a/src/main.c +++ b/src/main.c @@ -32,31 +32,34 @@ extern Map *worldRPG[]; /* Game data (defined in "game.h")*/ -Game game = {NULL, - {12 * PXSIZE, - 36 * PXSIZE, - 0, - 0, - 100, - SPEED, - false, - 0, - false, - false, - true, - {}}, - {{}, {}, 0}, - false, - false, - false, - 0, +Game game = { + NULL, + {12 * PXSIZE, + 36 * PXSIZE, + 0, + 0, + 100, + SPEED, + false, + 0, + false, + false, + true, + {}}, + {{}, {}, 0}, + false, + false, + false, + 0, - /* debug variables*/ - false, - false, - false, - {}, - 100}; + /* debug variables*/ + false, + false, + false, + {}, + {}, + 100, +}; /* screen capture management code. TODO: Clean this up! */ @@ -117,6 +120,17 @@ int main(void) { } timer_start(timer); + extern char *_message_buffer; + _message_buffer = NULL; + _message_buffer = malloc(MESSAGE_BUFFER_SZ); + if(!_message_buffer) { + dtext(64, 64, C_BLACK, + "Failed to allocate the message buffer: not " + "enough RAM available. Press any key to quit."); + dupdate(); + getkey(); + return 0; + } game_init(&game); #if USB_FEATURE @@ -213,5 +227,6 @@ int main(void) { #endif timer_stop(timer); + free(_message_buffer); return 1; } diff --git a/src/npc.h b/src/npc.h index 3d02e01..e267af7 100644 --- a/src/npc.h +++ b/src/npc.h @@ -13,7 +13,6 @@ enum { NPC_FRIENDLY = 1, // The player's team NPC_HOSTILE = 2, // to the player NPC_ALL = 3 - }; /* /!\ Warning /!\