diff --git a/CMakeLists.txt b/CMakeLists.txt index 50584f93..5e494012 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,7 @@ add_executable(${PROJECT_NAME}) set(ROOT_DIR "${CMAKE_SOURCE_DIR}") set(TOOLS_DIR "${ROOT_DIR}/tools") set(ASSETS_DIR "assets") +set(TEMP_DIR "temp") # Include tools add_subdirectory(tools) @@ -75,6 +76,8 @@ elseif(TARGET_TYPE STREQUAL game) GAME_VERSION=1.0 ) + + # Characters set(DIR_CHARS poker/characters) tool_vn_character(vn_penny ${DIR_CHARS}/penny/character.xml ${DIR_CHARS}/penny.png @@ -88,15 +91,31 @@ elseif(TARGET_TYPE STREQUAL game) tool_vn_character(vn_sammy ${DIR_CHARS}/sammy/character.xml ${DIR_CHARS}/sammy.png ) + tool_vn_character(vn_jenny + ${DIR_CHARS}/jenny/character.xml ${DIR_CHARS}/jenny.png + ) + + # World + tool_copy(texture_pub + poker/world/pub/pub_skywall.png poker/pub_skywall.png + ) + tool_copy(texture_cards + poker/cards_normal.png poker/cards.png + ) tool_assets( shader_textured font_opensans texture_test + vn_penny vn_lucy vn_julie vn_sammy + + texture_pub + texture_cards + locale_en ) endif() diff --git a/src/game/poker/characters/characters.c b/src/game/poker/characters/characters.c new file mode 100644 index 00000000..2da2c4c3 --- /dev/null +++ b/src/game/poker/characters/characters.c @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2021 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "characters.h" + +pokercharacterdefinition_t POKER_CHARACTER_DEFINITIONS[] = { + { + "Lucy", + POKER_CHARACTER_LUCY_TEXTURE, + &pokerCharacterLucyInit + }, + + { + "Julie", + POKER_CHARACTER_JULIE_TEXTURE, + &pokerCharacterJulieInit + }, + + { + "Penny", + POKER_CHARACTER_PENNY_TEXTURE, + &pokerCharacterPennyInit + }, + + { + "Sammy", + POKER_CHARACTER_SAMMY_TEXTURE, + &pokerCharacterSammyInit + }, + + { + "Jenny", + POKER_CHARACTER_JENNY_TEXTURE, + &pokerCharacterJennyInit + } +}; + +void pokerCharacterInit(vncharacter_t *crctr, texture_t *txtr, uint8_t i) { + vnCharacterInit(crctr, txtr); + POKER_CHARACTER_DEFINITIONS[i].init(crctr); +} \ No newline at end of file diff --git a/src/game/poker/characters/characters.h b/src/game/poker/characters/characters.h new file mode 100644 index 00000000..d0cfc79c --- /dev/null +++ b/src/game/poker/characters/characters.h @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2021 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "../../../libs.h" +#include "../../../vn/vncharacter.h" +#include "../../../display/texture.h" +#include "jenny.h" +#include "julie.h" +#include "lucy.h" +#include "penny.h" +#include "sammy.h" + +typedef void pokercharacterinitmethod_t(vncharacter_t *c); + +typedef struct { + char *name; + char *fileTexture; + pokercharacterinitmethod_t *init; +} pokercharacterdefinition_t; + +extern pokercharacterdefinition_t POKER_CHARACTER_DEFINITIONS[]; + +void pokerCharacterInit(vncharacter_t *crctr, texture_t *txtr, uint8_t i); \ No newline at end of file diff --git a/src/game/poker/characters/jenny.c b/src/game/poker/characters/jenny.c new file mode 100644 index 00000000..6dd83622 --- /dev/null +++ b/src/game/poker/characters/jenny.c @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2021 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "jenny.h" + +void pokerCharacterJennyInit(vncharacter_t *vnc) { + // Base Layer + vnCharacterLayerAdd(vnc, 1, 0, 0, 0, 0, 1095, 2029); + + // Layers + vnCharacterLayerAdd(vnc, 3, + 1095, 0, + 608, 250, + 280, 123 + ); + + vnCharacterLayerAdd(vnc, 3, + 1095, 123, + 608, 250, + 280, 123 + ); +} diff --git a/src/game/poker/characters/jenny.h b/src/game/poker/characters/jenny.h new file mode 100644 index 00000000..3fbabf15 --- /dev/null +++ b/src/game/poker/characters/jenny.h @@ -0,0 +1,16 @@ +/** + * Copyright (c) 2021 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "../../../libs.h" +#include "../../../vn/vncharacter.h" +#include "../../../display/texture.h" +#include "../../../file/asset.h" + +#define POKER_CHARACTER_JENNY_TEXTURE "poker/characters/jenny.png" + +void pokerCharacterJennyInit(vncharacter_t *vnc); diff --git a/src/game/poker/characters/julie.c b/src/game/poker/characters/julie.c new file mode 100644 index 00000000..a085002f --- /dev/null +++ b/src/game/poker/characters/julie.c @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2021 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "julie.h" + +void pokerCharacterJulieInit(vncharacter_t *vnc) { + // Base Layer + vnCharacterLayerAdd(vnc, 1, 0, 0, 0, 0, 1053, 1961); + + // Layers + vnCharacterLayerAdd(vnc, 4, + 1053, 0, + 353, 119, + 344, 351 + ); + + vnCharacterLayerAdd(vnc, 12, + 1053, 351, + 353, 119, + 344, 351 + ); + + vnCharacterLayerAdd(vnc, 4, + 1053, 702, + 353, 119, + 344, 351 + ); + + vnCharacterLayerAdd(vnc, 2, + 1053, 1053, + 353, 119, + 344, 351 + ); +} diff --git a/src/game/poker/characters/julie.h b/src/game/poker/characters/julie.h new file mode 100644 index 00000000..e6f78e2c --- /dev/null +++ b/src/game/poker/characters/julie.h @@ -0,0 +1,16 @@ +/** + * Copyright (c) 2021 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "../../../libs.h" +#include "../../../vn/vncharacter.h" +#include "../../../display/texture.h" +#include "../../../file/asset.h" + +#define POKER_CHARACTER_JULIE_TEXTURE "poker/characters/julie.png" + +void pokerCharacterJulieInit(vncharacter_t *vnc); diff --git a/src/game/poker/characters/lucy.c b/src/game/poker/characters/lucy.c new file mode 100644 index 00000000..3e3652a3 --- /dev/null +++ b/src/game/poker/characters/lucy.c @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2021 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + + +#include "lucy.h" + +void pokerCharacterLucyInit(vncharacter_t *vnc) { + // Base Layer + vnCharacterLayerAdd(vnc, 1, 0, 0, 0, 0, 1440, 2240); + + // Layers + + vnCharacterLayerAdd(vnc, 5, + 1440, 0, + 675, 327, + 295, 235 + ); + + vnCharacterLayerAdd(vnc, 12, + 1440, 235, + 675, 327, + 295, 235 + ); + + vnCharacterLayerAdd(vnc, 5, + 1440, 470, + 675, 327, + 295, 235 + ); +} diff --git a/src/game/poker/characters/lucy.h b/src/game/poker/characters/lucy.h new file mode 100644 index 00000000..f86e7e42 --- /dev/null +++ b/src/game/poker/characters/lucy.h @@ -0,0 +1,16 @@ +/** + * Copyright (c) 2021 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "../../../libs.h" +#include "../../../vn/vncharacter.h" +#include "../../../display/texture.h" +#include "../../../file/asset.h" + +#define POKER_CHARACTER_LUCY_TEXTURE "poker/characters/lucy.png" + +void pokerCharacterLucyInit(vncharacter_t *vnc); diff --git a/src/game/poker/characters/penny.c b/src/game/poker/characters/penny.c new file mode 100644 index 00000000..de77581f --- /dev/null +++ b/src/game/poker/characters/penny.c @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2021 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "penny.h" + +void pokerCharacterPennyInit(vncharacter_t *vnc) { + // Base Layer + vnCharacterLayerAdd(vnc, 1, 0, 0, 0, 0, 1000, 1920); + + // Layers + vnCharacterLayerAdd(vnc, 5, + 1000, 0, + 367, 256, + 280, 280 + ); + + vnCharacterLayerAdd(vnc, 4, + 1000, 280, + 367, 256, + 280, 280 + ); + + vnCharacterLayerAdd(vnc, 12, + 1000, 560, + 367, 256, + 280, 280 + ); +} \ No newline at end of file diff --git a/src/game/poker/characters/penny.h b/src/game/poker/characters/penny.h new file mode 100644 index 00000000..2e404123 --- /dev/null +++ b/src/game/poker/characters/penny.h @@ -0,0 +1,16 @@ +/** + * Copyright (c) 2021 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "../../../libs.h" +#include "../../../vn/vncharacter.h" +#include "../../../display/texture.h" +#include "../../../file/asset.h" + +#define POKER_CHARACTER_PENNY_TEXTURE "poker/characters/penny.png" + +void pokerCharacterPennyInit(vncharacter_t *vnc); \ No newline at end of file diff --git a/src/game/poker/characters/sammy.c b/src/game/poker/characters/sammy.c new file mode 100644 index 00000000..5c662350 --- /dev/null +++ b/src/game/poker/characters/sammy.c @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2021 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "sammy.h" + +void pokerCharacterSammyInit(vncharacter_t *vnc) { + // Base Layer + vnCharacterLayerAdd(vnc, 1, 0, 0, 0, 0, 731, 2122); + + // Layers + vnCharacterLayerAdd(vnc, 4, + 731, 0, + 215, 264, + 307, 213 + ); + + vnCharacterLayerAdd(vnc, 12, + 731, 213, + 215, 264, + 307, 213 + ); + + vnCharacterLayerAdd(vnc, 5, + 731, 426, + 215, 264, + 307, 213 + ); +} diff --git a/src/game/poker/characters/sammy.h b/src/game/poker/characters/sammy.h new file mode 100644 index 00000000..a6a65504 --- /dev/null +++ b/src/game/poker/characters/sammy.h @@ -0,0 +1,16 @@ +/** + * Copyright (c) 2021 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "../../../libs.h" +#include "../../../vn/vncharacter.h" +#include "../../../display/texture.h" +#include "../../../file/asset.h" + +#define POKER_CHARACTER_SAMMY_TEXTURE "poker/characters/sammy.png" + +void pokerCharacterSammyInit(vncharacter_t *vnc); \ No newline at end of file diff --git a/src/game/poker/pokerdiscussion.c b/src/game/poker/pokerdiscussion.c index bf31115b..b6950e3e 100644 --- a/src/game/poker/pokerdiscussion.c +++ b/src/game/poker/pokerdiscussion.c @@ -21,7 +21,6 @@ void pokerDiscussionGet( discussion->count++; discussion->messages[0] = "Match Start"; discussion->players[0] = POKER_WORLD_DEALER_INDEX; - discussion->emotions[0] = VN_CHARACTER_EMOTION_BORED; break; // Round Start Conversations @@ -29,7 +28,6 @@ void pokerDiscussionGet( discussion->count++; discussion->messages[0] = "Round Start"; discussion->players[0] = POKER_WORLD_DEALER_INDEX; - discussion->emotions[0] = VN_CHARACTER_EMOTION_BORED; break; // Round Start Conversations @@ -37,7 +35,6 @@ void pokerDiscussionGet( discussion->count++; discussion->messages[0] = "Blinds\nhave been taken."; discussion->players[0] = POKER_WORLD_DEALER_INDEX; - discussion->emotions[0] = VN_CHARACTER_EMOTION_BORED; break; // Deal @@ -45,7 +42,6 @@ void pokerDiscussionGet( discussion->count++; discussion->messages[0] = "Cards dealt."; discussion->players[0] = POKER_WORLD_DEALER_INDEX; - discussion->emotions[0] = VN_CHARACTER_EMOTION_BORED; break; // Betting conversations @@ -53,35 +49,30 @@ void pokerDiscussionGet( discussion->count++; discussion->messages[0] = "I fold."; discussion->players[0] = data->playerCause; - discussion->emotions[0] = VN_CHARACTER_EMOTION_ANGRY; break; case POKER_DISCUSSION_REASON_PLAYER_CHECKING: discussion->count++; discussion->messages[0] = "I check."; discussion->players[0] = data->playerCause; - discussion->emotions[0] = VN_CHARACTER_EMOTION_ANGRY; break; case POKER_DISCUSSION_REASON_PLAYER_CALLING: discussion->count++; discussion->messages[0] = "I call."; discussion->players[0] = data->playerCause; - discussion->emotions[0] = VN_CHARACTER_EMOTION_SMUG; break; case POKER_DISCUSSION_REASON_PLAYER_RAISING: discussion->count++; discussion->messages[0] = "I raise."; discussion->players[0] = data->playerCause; - discussion->emotions[0] = VN_CHARACTER_EMOTION_BOASTFUL; break; case POKER_DISCUSSION_REASON_PLAYER_ALL_IN: discussion->count++; discussion->messages[0] = "All in."; discussion->players[0] = data->playerCause; - discussion->emotions[0] = VN_CHARACTER_EMOTION_ANGRY_PROUD; break; // Flops @@ -89,14 +80,12 @@ void pokerDiscussionGet( discussion->count++; discussion->messages[0] = "Doing the flop."; discussion->players[0] = POKER_WORLD_DEALER_INDEX; - discussion->emotions[0] = VN_CHARACTER_EMOTION_ANIME_MOM; break; case POKER_DISCUSSION_REASON_BETTING_DONE: discussion->count++; discussion->messages[0] = "Winner Winner Chicken Dinner"; discussion->players[0] = POKER_WORLD_DEALER_INDEX; - discussion->emotions[0] = VN_CHARACTER_EMOTION_SMUG_VERY; break; // Fallback @@ -104,7 +93,6 @@ void pokerDiscussionGet( discussion->count++; discussion->messages[0] = "Hmm, this seems to be an error message."; discussion->players[0] = POKER_WORLD_DEALER_INDEX; - discussion->emotions[0] = VN_CHARACTER_EMOTION_CONCERNED_WORRIED; break; } } @@ -146,8 +134,7 @@ void pokerDiscussionQueue(pokerdiscussiondata_t *data) { pokerGameActionLookAdd(data->poker, player); vnConversationTalk(&data->poker->scene.conversation, discussion.messages[i], - data->poker->scene.characters + player, - discussion.emotions[i] + data->poker->scene.characters + player ); } } \ No newline at end of file diff --git a/src/game/poker/pokerdiscussion.h b/src/game/poker/pokerdiscussion.h index 837fe2d5..a1c7a063 100644 --- a/src/game/poker/pokerdiscussion.h +++ b/src/game/poker/pokerdiscussion.h @@ -38,7 +38,6 @@ typedef struct { typedef struct { char *messages[POKER_DISCUSSION_MESSAGE_COUNT_MAX]; uint8_t players[POKER_DISCUSSION_MESSAGE_COUNT_MAX]; - uint8_t emotions[POKER_DISCUSSION_MESSAGE_COUNT_MAX]; uint8_t count; } pokerdiscussion_t; diff --git a/src/game/poker/pokergameassets.c b/src/game/poker/pokergameassets.c index 5859827f..44433846 100644 --- a/src/game/poker/pokergameassets.c +++ b/src/game/poker/pokergameassets.c @@ -20,11 +20,8 @@ bool pokerGameAssetsInit(pokergameassets_t *assets) { // Load the world textures. assetTextureLoad(&assets->testTexture, "textures/test_texture.png"); - assetTextureLoad(&assets->cardTexture, "poker/cards_normal.png"); - assetTextureLoad(&assets->roomTexture, "poker/world/pub/pub_skywall.png"); - - // Load the character textures. - assetTextureLoad(&assets->pennyTexture, "poker/characters/penny/sprites/sheet.png"); + assetTextureLoad(&assets->cardTexture, "poker/cards.png"); + assetTextureLoad(&assets->roomTexture, "poker/pub_skywall.png"); return true; } diff --git a/src/game/poker/pokergameassets.h b/src/game/poker/pokergameassets.h index 4cbdc613..92c36d76 100644 --- a/src/game/poker/pokergameassets.h +++ b/src/game/poker/pokergameassets.h @@ -10,6 +10,9 @@ #include "../../file/asset.h" #include "../../locale/language.h" #include "../../display/texture.h" +#include "../../vn/vncharacter.h" +#include "../../poker/common.h" +#include "characters/characters.h" typedef struct { font_t font; @@ -20,7 +23,7 @@ typedef struct { texture_t roomTexture; texture_t cardTexture; - texture_t pennyTexture; + texture_t characterTextures[POKER_PLAYER_COUNT_MAX]; } pokergameassets_t; /** diff --git a/src/game/poker/pokerworld.c b/src/game/poker/pokerworld.c index 3ce45915..37b42cdb 100644 --- a/src/game/poker/pokerworld.c +++ b/src/game/poker/pokerworld.c @@ -13,6 +13,7 @@ void pokerWorldInit( pokergameassets_t *assets ) { vncharacter_t *character; + texture_t *texture; uint8_t i; world->seat = POKER_WORLD_SEAT_DEALER; @@ -24,19 +25,21 @@ void pokerWorldInit( // Initialize the players for(i = 0x00; i < POKER_PLAYER_COUNT_MAX; i++) { character = scene->characters + scene->characterCount; - vnCharacterInit(character, &assets->pennyTexture, - POKER_WORLD_PENNY_BASE_WIDTH, POKER_WORLD_PENNY_BASE_HEIGHT, - POKER_WORLD_PENNY_FACE_X, POKER_WORLD_PENNY_FACE_Y, - POKER_WORLD_PENNY_FACE_WIDTH, POKER_WORLD_PENNY_FACE_HEIGHT - ); - character->x = POKER_WORLD_SEAT_POSITION_X(POKER_WORLD_SEAT_FOR_PLAYER(i)); - character->y = POKER_WORLD_SEAT_POSITION_Y; - character->z = POKER_WORLD_SEAT_POSITION_Z(POKER_WORLD_SEAT_FOR_PLAYER(i)); - character->yaw = POKER_WORLD_SEAT_ROTATION(POKER_WORLD_SEAT_FOR_PLAYER(i)); + texture = assets->characterTextures + i; + assetTextureLoad(texture, POKER_CHARACTER_DEFINITIONS[i].fileTexture); + pokerCharacterInit(character, texture, i); + pokerWorldSitCharacter(character, POKER_WORLD_SEAT_FOR_PLAYER(i)); scene->characterCount++; } } +void pokerWorldSitCharacter(vncharacter_t *character, uint8_t seat) { + character->x = POKER_WORLD_SEAT_POSITION_X(seat); + character->y = POKER_WORLD_SEAT_POSITION_Y; + character->z = POKER_WORLD_SEAT_POSITION_Z(seat); + character->yaw = POKER_WORLD_SEAT_ROTATION(seat); +} + void pokerWorldLookAtPlayer( vnscene_t *scene, uint8_t playerIndex ) { diff --git a/src/game/poker/pokerworld.h b/src/game/poker/pokerworld.h index 12bcd649..1bf7cf59 100644 --- a/src/game/poker/pokerworld.h +++ b/src/game/poker/pokerworld.h @@ -18,7 +18,7 @@ #include "pokergameassets.h" /** How far away from the camera are the characters distanced */ -#define POKER_WORLD_SEAT_DISTANCE -0.75f +#define POKER_WORLD_SEAT_DISTANCE -1.25f /** How rotated is the player at a given seat */ #define POKER_WORLD_SEAT_ROTATION(n) (n * mathDeg2Rad(45.0f)) @@ -81,6 +81,14 @@ void pokerWorldInit( pokergameassets_t *assets ); +/** + * Adjusts a specific VN player to sit at the given index + * + * @param character Character to place in the seat. + * @param seat Seat to put the character in. + */ +void pokerWorldSitCharacter(vncharacter_t *character, uint8_t seat); + /** * Adjusts the camera to look at a specific player. You can use this to look at * the dealer by referencing the POKER_PLAYER_HUMAN_INDEX as the index. diff --git a/src/vn/conversation/talk.c b/src/vn/conversation/talk.c index 2dc2313e..ba7ac4cd 100644 --- a/src/vn/conversation/talk.c +++ b/src/vn/conversation/talk.c @@ -12,11 +12,6 @@ void _vnConversationTalkStart(queue_t *queue, queueaction_t *action,uint8_t i) { data = (vnconversationitemdata_t *)action->data; vnTextBoxSetText(&data->conversation->textbox, data->text); - - if(data->character != NULL) { - data->character->emotion = data->emotion; - data->character->talking = true; - } } void _vnConversationTalkUpdate(queue_t *queue,queueaction_t *action,uint8_t i) { @@ -25,7 +20,6 @@ void _vnConversationTalkUpdate(queue_t *queue,queueaction_t *action,uint8_t i) { if(data->conversation->textbox.state & VN_TEXTBOX_STATE_CLOSED) { - if(data->character != NULL) data->character->talking = false; queueNext(queue); } } @@ -33,8 +27,7 @@ void _vnConversationTalkUpdate(queue_t *queue,queueaction_t *action,uint8_t i) { queueaction_t * vnConversationTalk( vnconversation_t *conversation, char *text, - vncharacter_t *character, - uint8_t emotion + vncharacter_t *character ) { queueaction_t *action; vnconversationitemdata_t *data; @@ -46,7 +39,6 @@ queueaction_t * vnConversationTalk( data = (vnconversationitemdata_t *)action->data; data->text = text; data->character = character; - data->emotion = emotion; return action; } \ No newline at end of file diff --git a/src/vn/conversation/talk.h b/src/vn/conversation/talk.h index 1c31d4e4..32107312 100644 --- a/src/vn/conversation/talk.h +++ b/src/vn/conversation/talk.h @@ -29,6 +29,5 @@ void _vnConversationTalkUpdate(queue_t *q, queueaction_t *a, uint8_t i); queueaction_t * vnConversationTalk( vnconversation_t *conversation, char *text, - vncharacter_t *character, - uint8_t emotion + vncharacter_t *character ); \ No newline at end of file diff --git a/src/vn/conversation/vnconversation.h b/src/vn/conversation/vnconversation.h index af14f38c..ef89950e 100644 --- a/src/vn/conversation/vnconversation.h +++ b/src/vn/conversation/vnconversation.h @@ -25,9 +25,6 @@ typedef struct { /** Character this conversation piece belongs to */ vncharacter_t *character; - - /** Character's emotion */ - uint8_t emotion; } vnconversationitemdata_t; /** Representation of a conversation, laid out similarly to a timeline. */ diff --git a/src/vn/vncharacter.c b/src/vn/vncharacter.c index 9ae309c5..388075ca 100644 --- a/src/vn/vncharacter.c +++ b/src/vn/vncharacter.c @@ -8,12 +8,7 @@ #include "vncharacter.h" -void vnCharacterInit( - vncharacter_t *character, texture_t *texture, - int32_t baseWidth, int32_t baseHeight, - int32_t faceX, int32_t faceY, - int32_t faceWidth, int32_t faceHeight -) { +void vnCharacterInit(vncharacter_t *character, texture_t *texture) { character->x = 0; character->y = 0; character->z = 0; @@ -24,89 +19,36 @@ void vnCharacterInit( character->scaleX = 1; character->scaleY = 1; - + character->layerCount = 0; character->texture = texture; - character->talking = false; - character->blinkStart = 0; - - character->baseWidth = baseWidth; - character->baseHeight = baseHeight; - character->faceX = faceX; - character->faceY = faceY; - character->faceWidth = faceWidth; - character->faceHeight = faceHeight; - - character->emotion = VN_CHARACTER_EMOTION_HAPPY; // Init the primitive. primitiveInit(&character->primitive, - QUAD_VERTICE_COUNT * VN_CHARACTER_QUAD_COUNT, - QUAD_INDICE_COUNT * VN_CHARACTER_QUAD_COUNT - ); - - // Buffer the base quad, this never changes (currently) - _vnCharacterBuffer(character, 0, 0, baseWidth, baseHeight, 0, 0, 0); - _vnCharacterFaceBuffer(character, 0, VN_CHARACTER_QUAD_EYEBROWS); - _vnCharacterFaceBuffer(character, 0, VN_CHARACTER_QUAD_EYES); - _vnCharacterFaceBuffer(character, 0, VN_CHARACTER_QUAD_MOUTH); -} - -void _vnCharacterBuffer(vncharacter_t *character, - int32_t x, int32_t y, int32_t width, int32_t height, int32_t tx, int32_t ty, - int32_t i -) { - // Calc size for each pixel. - float ps = 1.0f / (float)character->baseHeight;// Prefer Height - float tpx = 1.0f / (float)character->texture->width; - float tpy = 1.0f / (float)character->texture->height; - - // Center inside the character - x -= character->baseWidth / 2; - y += character->baseHeight / 2; - - quadBuffer(&character->primitive, 0.001f * (float)i, - (float)x * ps, 1 - (float)y * ps, - (float)tx * tpx, (float)ty * tpy, - (float)(x + width) * ps, 1 - (float)(y + height) * ps, - (float)(tx + width) * tpx, (float)(ty + height) * tpy, - i * QUAD_VERTICE_COUNT, i * QUAD_INDICE_COUNT - ); -} - -void _vnCharacterFaceBuffer(vncharacter_t *character, - int32_t col, int32_t i -) { - _vnCharacterBuffer(character, - character->faceX, character->faceY, - character->faceWidth, character->faceHeight, - character->baseWidth + (character->faceWidth * col), - character->faceHeight * (i -1), - i + QUAD_VERTICE_COUNT * VN_CHARACTER_LAYERS_MAX, + QUAD_INDICE_COUNT * VN_CHARACTER_LAYERS_MAX ); } void vnCharacterUpdate(vncharacter_t *character, engine_t *engine) { - uint8_t eyes, mouth, eyebrows; float t; + float speed, amount; // Setup frames based on the emotion. - mouth = character->emotion % 0x04; - eyes = (character->emotion/0x04) % 0x04; - eyebrows = ((character->emotion/0x04)/0x04) % 0x05; - - _vnCharacterFaceBuffer(character, eyebrows, VN_CHARACTER_QUAD_EYEBROWS); - _vnCharacterFaceBuffer(character, eyes, VN_CHARACTER_QUAD_EYES); - - mouth *= VN_CHARACTER_TALKING_FRAME_COUNT; - if(character->talking) { - t = animForwardAndBackwardScaled(mathModFloat( - engine->time.current * animTimeScaleFromFrameTime(3, 0.2f), 1.0f - )); - mouth += (uint8_t)(t * VN_CHARACTER_TALKING_FRAME_COUNT); - } - _vnCharacterFaceBuffer(character, mouth, VN_CHARACTER_QUAD_MOUTH); + // mouth = character->emotion % 0x04; + // eyes = (character->emotion/0x04) % 0x04; + // eyebrows = ((character->emotion/0x04)/0x04) % 0x05; + // _vnCharacterFaceBuffer(character, eyebrows, VN_CHARACTER_QUAD_EYEBROWS); + // _vnCharacterFaceBuffer(character, eyes, VN_CHARACTER_QUAD_EYES); + // mouth *= VN_CHARACTER_TALKING_FRAME_COUNT; + // if(character->talking) { + // t = animForwardAndBackwardScaled(mathModFloat( + // engine->time.current * animTimeScaleFromFrameTime(3, 0.2f), 1.0f + // )); + // mouth += (uint8_t)(t * VN_CHARACTER_TALKING_FRAME_COUNT); + // } + // _vnCharacterFaceBuffer(character, mouth, VN_CHARACTER_QUAD_MOUTH); // float n; // // Update the blinking frames // n = (engine->time.current - character->blinkStart) * 3.0f; @@ -134,7 +76,6 @@ void vnCharacterUpdate(vncharacter_t *character, engine_t *engine) { // } // Update the scale frames for breathing / talk breathing - float speed, amount; speed = 0.2f; amount = 90.0f; t = animForwardAndBackwardScaled( @@ -145,6 +86,60 @@ void vnCharacterUpdate(vncharacter_t *character, engine_t *engine) { character->scaleY = 1 - t; } + +uint8_t vnCharacterLayerAdd(vncharacter_t *character, + uint8_t frames, + int32_t lx, int32_t ly, + int32_t x, int32_t y, + int32_t width, int32_t height +) { + uint8_t i; + vncharacterlayer_t *layer; + + i = character->layerCount++; + layer = character->layers + i; + + layer->frames = frames; + layer->lx = lx; + layer->ly = ly; + layer->x = x; + layer->y =y; + layer->width = width; + layer->height = height; + + vnCharacterLayerSetFrame(character, i, 0); + return i; +} + +void vnCharacterLayerSetFrame(vncharacter_t *character, uint8_t l, uint8_t f) { + vncharacterlayer_t *layer; + vncharacterlayer_t *base; + + layer = character->layers + l; + base = character->layers; + f = f % layer->frames; + + float ps = 1.0f / (float)base->height; + float tpx = 1.0f / (float)character->texture->width; + float tpy = 1.0f / (float)character->texture->height; + + int32_t x = layer->x - (base->width / 2); + int32_t y = layer->y + (base->height / 2); + int32_t tx = layer->lx + (layer->width * f); + + quadBuffer(&character->primitive, 0.001f * (float)l, + (float)x * ps, 1 - (float)y * ps, + (float)tx * tpx, + (float)layer->ly * tpy, + + (float)(x + layer->width) * ps, + 1 - (float)(y + layer->height) * ps, + (float)(tx + layer->width) * tpx, + (float)(layer->ly + layer->height) * tpy, + l * QUAD_VERTICE_COUNT, l * QUAD_INDICE_COUNT + ); +} + void vnCharacterRender(vncharacter_t *character, shader_t *shader) { shaderUsePositionAndScale(shader, character->x, character->y, character->z, @@ -152,7 +147,9 @@ void vnCharacterRender(vncharacter_t *character, shader_t *shader) { character->scaleX, character->scaleY, 1 ); shaderUseTexture(shader, character->texture); - primitiveDraw(&character->primitive, 0, -1); + primitiveDraw( + &character->primitive, 0, character->layerCount * QUAD_INDICE_COUNT + ); } void vnCharacterDispose(vncharacter_t *character) { diff --git a/src/vn/vncharacter.h b/src/vn/vncharacter.h index 27b05440..15238922 100644 --- a/src/vn/vncharacter.h +++ b/src/vn/vncharacter.h @@ -17,164 +17,38 @@ #include "../display/animation/easing.h" #define VN_CHARACTER_BLINK_TIME_RANGE_MAX 6 -#define VN_CHARACTER_SIZE 0.5 - -/** How many quads the VN Character has. Base, Eyes, Mouth and Eyebrows */ -#define VN_CHARACTER_QUAD_COUNT 4 - -/** The Quads */ -#define VN_CHARACTER_QUAD_BASE 0 -#define VN_CHARACTER_QUAD_EYEBROWS 1 -#define VN_CHARACTER_QUAD_EYES 2 -#define VN_CHARACTER_QUAD_MOUTH 3 - -/** How many frames does each mouth set have */ -#define VN_CHARACTER_TALKING_FRAME_COUNT 3 - -#define VN_CHARACTER_EMOTION_BORED 0x00 -#define VN_CHARACTER_EMOTION_BORED_SMILING 0x01 -#define VN_CHARACTER_EMOTION_BORED_DISAGREE 0x02 -#define VN_CHARACTER_EMOTION_BORED_AGREE 0x03 -#define VN_CHARACTER_EMOTION_SHORT 0x04 -#define VN_CHARACTER_EMOTION_SMUG_SLIGHT 0x05 -#define VN_CHARACTER_EMOTION_BORED_ANNOYED 0x06 -#define VN_CHARACTER_EMOTION_BORED_PROUD 0x07 -#define VN_CHARACTER_EMOTION_BORED_THINKING 0x08 -#define VN_CHARACTER_EMOTION_HAPPY_THINKING 0x09 -#define VN_CHARACTER_EMOTION_SERIOUS_THINKING 0x0A -#define VN_CHARACTER_EMOTION_SMUG_THINKING_SLIGHT 0x0B -#define VN_CHARACTER_EMOTION_XXXX_THINKING 0x0C// "concerned thinking" -#define VN_CHARACTER_EMOTION_HAPPY_FAKE_THINKING 0x0D -#define VN_CHARACTER_EMOTION_XXXX_THINKING2 0x0E// "serious concerned thinking" -#define VN_CHARACTER_EMOTION_XXXX_THINKING3 0x0F // "Happy pleased thinking" -#define VN_CHARACTER_EMOTION_BORED_LISTENING 0x10 -#define VN_CHARACTER_EMOTION_HUMBLED 0x11 -#define VN_CHARACTER_EMOTION_CONCERNED_1 0x12 -#define VN_CHARACTER_EMOTION_PROUD 0x13 -#define VN_CHARACTER_EMOTION_DEADPAN 0x14 -#define VN_CHARACTER_EMOTION_SMIRK 0x15 -#define VN_CHARACTER_EMOTION_CONCERNED_2 0x16 -#define VN_CHARACTER_EMOTION_TEASING 0x17 -#define VN_CHARACTER_EMOTION_XXXX_THINKING4 0x18// "concerned thinking lightly" -#define VN_CHARACTER_EMOTION_XXXX_THINKING5 0x19// "daydreaming" -#define VN_CHARACTER_EMOTION_XXXX_THINKING6 0x1A// "concerned thinking heavy" -#define VN_CHARACTER_EMOTION_XXXX_THINKING7 0x1B// "pleasant daydreaming" -#define VN_CHARACTER_EMOTION_XXXX_THINKING8 0x1C// not really sure -#define VN_CHARACTER_EMOTION_ANIME_MOM 0x1D -#define VN_CHARACTER_EMOTION_XXXX_THINKING9 0x1E// not really sure -#define VN_CHARACTER_EMOTION_ANIME_MOM_SMUG 0x1F -#define VN_CHARACTER_EMOTION_CURIOUS 0x20 -#define VN_CHARACTER_EMOTION_HAPPY 0x21 -#define VN_CHARACTER_EMOTION_CONCERNED_WORRIED 0x22 -#define VN_CHARACTER_EMOTION_HAPPY_PROUD_SLIGHT 0x23 -#define VN_CHARACTER_EMOTION_NOT_BELIEVING 0x24//"Mhm, suuure" -#define VN_CHARACTER_EMOTION_HAPPY_TIRED 0x25 -#define VN_CHARACTER_EMOTION_CONCERNED_SLIGHT 0x26 -#define VN_CHARACTER_EMOTION_HAPPY_PROUD 0x27 -#define VN_CHARACTER_EMOTION_XXXX_THINKING10 0x28// sort of tsundere -#define VN_CHARACTER_EMOTION_XXXX_THINKING11 0x29// "thinking of something nice" -#define VN_CHARACTER_EMOTION_XXXX_THINKING12 0x2A// big sister vibes -#define VN_CHARACTER_EMOTION_XXXX_THINKING13 0x2B// "vibin" -#define VN_CHARACTER_EMOTION_XXXX_THINKING14 0x2C// not really sure -#define VN_CHARACTER_EMOTION_XXXX_THINKING15 0x2D// not really sure -#define VN_CHARACTER_EMOTION_XXXX_THINKING16 0x2E// not really sure -#define VN_CHARACTER_EMOTION_XXXX_THINKING17 0x2F// not really sure -#define VN_CHARACTER_EMOTION_CONCERNED 0x30 -#define VN_CHARACTER_EMOTION_RELIEVED 0x31 -#define VN_CHARACTER_EMOTION_CONCERNED_VERY 0x32 -#define VN_CHARACTER_EMOTION_RELIEVED_SMUG 0x33//"slightly smug" -#define VN_CHARACTER_EMOTION_CONCERNED_3 0x34// "slightly worried" -#define VN_CHARACTER_EMOTION_CONCERNED_4 0x35// "slightly smug" -#define VN_CHARACTER_DISAPPOINTED 0x36// "slightly worried" -#define VN_CHARACTER_EMOTION_CONCERNED_5 0x37// "slightly smugger" -#define VN_CHARACTER_EMOTION_CONCERNED_THINKING 0x38 -#define VN_CHARACTER_EMOTION_SMUG_1 0x39 -#define VN_CHARACTER_EMOTION_CONCERNED_THINKING_DEEP 0x3A -#define VN_CHARACTER_EMOTION_SMUG_2 0x3B -#define VN_CHARACTER_EMOTION_XXXX_THINKING18 0x3C// not really sure -#define VN_CHARACTER_EMOTION_XXXX_THINKING19 0x3D// not really sure -#define VN_CHARACTER_EMOTION_XXXX_THINKING20 0x3E// not really sure -#define VN_CHARACTER_EMOTION_XXXX_THINKING21 0x3F// not really sure -#define VN_CHARACTER_EMOTION_SERIOUS 0x40 -#define VN_CHARACTER_EMOTION_READY 0x41 -#define VN_CHARACTER_EMOTION_SERIOUS_ANGRY 0x42 -#define VN_CHARACTER_EMOTION_SMUG 0x43 -#define VN_CHARACTER_EMOTION_ANGRY 0x44 -#define VN_CHARACTER_EMOTION_ANGRY_PROUD 0x45 -#define VN_CHARACTER_EMOTION_ANGRY_VERY 0x46 -#define VN_CHARACTER_EMOTION_SMUG_VERY 0x47 -#define VN_CHARACTER_EMOTION_SERIOUS_THINKING_VERY 0x48 -#define VN_CHARACTER_EMOTION_SMUG_THINKING 0x49 -#define VN_CHARACTER_EMOTION_ANGRY_THINKING 0x4A -#define VN_CHARACTER_EMOTION_SMUG_THINKING_VERY 0x4B -#define VN_CHARACTER_EMOTION_XXXX_THINKING22 0x4C// not really sure -#define VN_CHARACTER_EMOTION_HAPPY_FAKE_THINKING_ANGRY 0x4D -#define VN_CHARACTER_EMOTION_XXXX_THINKING23 0x4E// not really sure -#define VN_CHARACTER_EMOTION_BOASTFUL 0x4F +#define VN_CHARACTER_LAYERS_MAX 6 typedef struct { + int32_t lx, ly, x, y, width, height; + uint8_t frames; +} vncharacterlayer_t; + +typedef struct { + /** Position, Rotation and Scale of the character */ float x, y, z; float yaw, pitch, roll; float scaleX, scaleY; - bool talking; - float blinkStart; - - uint8_t emotion; - + /** Quadded primitive */ primitive_t primitive; + /** Texture sheet for the character */ texture_t *texture; - int32_t baseWidth, baseHeight; - int32_t faceX, faceY; - int32_t faceWidth, faceHeight; + /** Count of layers */ + vncharacterlayer_t layers[VN_CHARACTER_LAYERS_MAX]; + uint8_t layerCount; } vncharacter_t; -/** - * Initialize a VN Character. - * - * @param character Character to initialize. - * @param texture The characters' texture. - * @param baseWidth The width of the base character within the texture. - * @param baseHeight The height of the base character within the texture. - * @param faceX The X position on the face that the faces are cropped. - * @param faceY The Y position on the face that the faces are cropped. - * @param faceWidth The width of the cropped face. - * @param faceHeight The height of the cropped face. - */ -void vnCharacterInit( - vncharacter_t *character, texture_t *texture, - int32_t baseWidth, int32_t baseHeight, - int32_t faceX, int32_t faceY, - int32_t faceWidth, int32_t faceHeight -); +void vnCharacterInit(vncharacter_t *character, texture_t *texture); -/** - * Buffer part of a VN Character texture onto the primitive. All the below units - * are believed to be in pixels, the relatives will be recalculated on the fly. - * - * @param character Character to buffer to. - * @param x Local X position of the VN Character to buffer to. - * @param y Local Y positon of the VN character to buffer to. - * @param width Width of the subarea. - * @param height Height of the subarea. - * @param tx Texture X position. - * @param ty Texture Y position. - * @param i Quad index to buffer to. - */ -void _vnCharacterBuffer(vncharacter_t *character, - int32_t x, int32_t y, int32_t width, int32_t height, int32_t tx, int32_t ty, - int32_t i +uint8_t vnCharacterLayerAdd(vncharacter_t *character, + uint8_t frames, + int32_t lx, int32_t ly, + int32_t x, int32_t y, + int32_t width, int32_t height ); - -/** - * Buffer the face of a VN Character to the primitive. - * - * @param character Character to buffer to. - * @param col Face Column. - * @param i Quad index to buffer to. - */ -void _vnCharacterFaceBuffer(vncharacter_t *character, int32_t col, int32_t i); +void vnCharacterLayerSetFrame(vncharacter_t *character, uint8_t l, uint8_t f); void vnCharacterUpdate(vncharacter_t *character, engine_t *engine); void vnCharacterRender(vncharacter_t *character, shader_t *shader); diff --git a/src/vn/vnscene.c b/src/vn/vnscene.c index 875e31b1..2caa3875 100644 --- a/src/vn/vnscene.c +++ b/src/vn/vnscene.c @@ -22,6 +22,7 @@ void vnSceneInit(vnscene_t *scene, font_t *font, texture_t *text) { scene->cameraLook.lookX = 0; scene->cameraLook.lookY = 0; scene->cameraLook.lookZ = VN_SCENE_DISTANCE_DEFAULT; + scene->cameraFov = 30.0f; // Reset character count scene->characterCount = 0x00; @@ -51,7 +52,7 @@ void vnSceneRenderWorld(vnscene_t *scene, engine_t *engine, shader_t *shader) { cameraLookAtStruct(&scene->camera, scene->cameraLook); // Set Camera Perspective - cameraPerspective(&scene->camera, 45, + cameraPerspective(&scene->camera, scene->cameraFov, engine->render.width/engine->render.height, 0.01f, 1000.0f ); diff --git a/src/vn/vnscene.h b/src/vn/vnscene.h index 492234cd..4b2f1c21 100644 --- a/src/vn/vnscene.h +++ b/src/vn/vnscene.h @@ -25,6 +25,7 @@ typedef struct { // Camera Targets cameralookat_t cameraLook; + float cameraFov; /** Camera used for rendering, updated frequently */ camera_t camera; diff --git a/tools/vn/CMakeLists.txt b/tools/vn/CMakeLists.txt index 6cf599f2..98e35c9a 100644 --- a/tools/vn/CMakeLists.txt +++ b/tools/vn/CMakeLists.txt @@ -4,8 +4,19 @@ # https://opensource.org/licenses/MIT function(tool_vn_character DEP_NAME IN OUT) - add_custom_target(${DEP_NAME} - COMMAND node ${TOOLS_DIR}/vn/character-sheet-generator.js --assets="${ASSETS_DIR}" --root="${ROOT_DIR}" --in="${IN}" --out="${OUT}" - COMMENT "Adding VN Character ${DEP_NAME}" + add_custom_command( + OUTPUT ${TEMP_DIR}/vn/${DEP_NAME}.c ${TEMP_DIR}/vn/${DEP_NAME}.h + COMMAND node ${TOOLS_DIR}/vn/character-sheet-generator.js --assets="${ASSETS_DIR}" --root="${ROOT_DIR}" --temp="${TEMP_DIR}" --in="${IN}" --out="${OUT}" --dep="${DEP_NAME}" + COMMENT "Generating VN Character ${DEP_NAME}" ) + + # target_sources(${PROJECT_NAME} + # PRIVATE + # ${CMAKE_CURRENT_BINARY_DIR}/${TEMP_DIR}/vn/${DEP_NAME}.c + # ${CMAKE_CURRENT_BINARY_DIR}/${TEMP_DIR}/vn/${DEP_NAME}.h + # ) + # target_include_directories(${PROJECT_NAME} + # PUBLIC + # ${CMAKE_CURRENT_BINARY_DIR}/${TEMP_DIR}/vn/ + # ) endfunction() \ No newline at end of file diff --git a/tools/vn/character-sheet-generator.js b/tools/vn/character-sheet-generator.js index 48e888cc..8d9e24c2 100644 --- a/tools/vn/character-sheet-generator.js +++ b/tools/vn/character-sheet-generator.js @@ -8,17 +8,22 @@ const { mkdirp } = require('../utils/file'); // Parse Args if(!args.root) throw new Error(`Missing root argument`); if(!args.assets) throw new Error(`Missing assets argument`); +if(!args.temp) throw new Error(`Missing temp argument`); if(!args.in) throw new Error(`Missing in argument`); if(!args.out) throw new Error(`Missing out argument`); +if(!args.dep) throw new Error(`Missing dep argument`); if(!args.in.endsWith('xml')) throw new Error(`Invalid in XML`); if(!args.out.endsWith('png')) throw new Error(`Invalid out PNG`); // Determine in and out. const root = path.resolve(args.root); const file = path.resolve(args.root, args.assets, args.in); -if(!fs.existsSync(file)) throw new Error(`Could not find ${file}`); const outFile = path.resolve(args.assets, args.out); -if(fs.existsSync(outFile)) return; + +const cOut = path.resolve(args.temp, 'vn', `${args.dep}.c`); +const hOut = path.resolve(args.temp, 'vn', `${args.dep}.h`); +if(!fs.existsSync(file)) throw new Error(`Could not find ${file}`); +if(fs.existsSync(outFile) && fs.existsSync(cOut) && fs.existsSync(hOut)) return; // Load XML const data = xml.xml2js(fs.readFileSync(file, 'utf-8')); @@ -49,6 +54,8 @@ const layers = character.elements let columnsMax = 0; let widthMax = 0; + let strLayers = ``; + layers.forEach((layer,row) => { if(!layer.width || !layer.height || !layer.x || !layer.y) { throw new Error(`Missing layer info`); @@ -86,9 +93,47 @@ const layers = character.elements ); } + strLayers += ` + vnCharacterLayerAdd(vnc, ${scan.length}, + ${baseImage.width}, ${y}, + ${layer.x}, ${layer.y}, + ${layer.width}, ${layer.height} + ); + `; + y += layer.height; } mkdirp(outFile); await imageWrite(out, outFile); + + mkdirp(cOut); + let name = character.attributes.name || args.name || args.dep; + + fs.writeFileSync(cOut, ` + #include "${args.dep}.h" + + void vnCharacter${name}Init(vncharacter_t *vnc, texture_t *texture) { + assetTextureLoad(texture, VN_CHARACTER_${name.toUpperCase()}_TEXTURE); + vnCharacterInit(vnc, texture); + + // Base Layer + vnCharacterLayerAdd(vnc, 1, 0, 0, 0, 0, ${baseImage.width}, ${baseImage.height}); + + // Layers + ${strLayers} + } + `); + + fs.writeFileSync(hOut, ` + #pragma once + #include + #include + #include + #include + + #define VN_CHARACTER_${name.toUpperCase()}_TEXTURE "${args.out}" + + void vnCharacter${name}Init(vncharacter_t *vnc, texture_t *texture); + `); })().catch(console.error); \ No newline at end of file