Merge dev into new_converter

This commit is contained in:
mibi88 2024-07-30 18:19:49 +02:00
parent bc8382ac65
commit 2202ec6d38
77 changed files with 1003 additions and 811 deletions

12
.clang-format Normal file
View file

@ -0,0 +1,12 @@
BasedOnStyle: LLVM
IndentWidth: 4
PointerAlignment: Right
SpaceBeforeAssignmentOperators: true
SpaceBeforeRangeBasedForLoopColon: false
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpaceBeforeParens: Never
IndentCaseBlocks: true
IncludeBlocks: Regroup
AllowShortBlocksOnASingleLine: Empty
ColumnLimit: 80

View file

@ -4,6 +4,16 @@
cmake_minimum_required(VERSION 3.15) cmake_minimum_required(VERSION 3.15)
project(MyAddin) project(MyAddin)
#set the color mode either to 1b or 2b
set(COLORMODE_fx 1b)
#set the color mode either to 1b, 2b or EGA64
set(COLORMODE_cg EGA64)
if(NOT "${COLORMODE_cg}" STREQUAL EGA64)
set(FXSDK_PLATFORM_LONG fx9860G_G3A)
set(FXSDK_PLATFORM fx)
endif()
include(GenerateG1A) include(GenerateG1A)
include(GenerateG3A) include(GenerateG3A)
@ -12,11 +22,6 @@ find_package(Gint 2.11 REQUIRED)
# Gint 2.11 is required, because we're using the new macros like GINT_RENDER_RGB # Gint 2.11 is required, because we're using the new macros like GINT_RENDER_RGB
find_package(LibProf 2.4 REQUIRED) find_package(LibProf 2.4 REQUIRED)
#set the color mode either to 1b or 2b
set(COLORMODE_fx 2b)
#set the color mode either to 1b, 2b or EGA64
set(COLORMODE_cg EGA64)
fxconv_declare_converters(assets/converters.py) fxconv_declare_converters(assets/converters.py)
set(SOURCES set(SOURCES
@ -38,8 +43,12 @@ set(ASSETS
) )
set(ASSETS_cg set(ASSETS_cg
assets-cg/demo_player.png assets-cg/player_male.png
assets-cg/player_female.png
assets-cg/npc/char/npc_male.png assets-cg/npc/char/npc_male.png
assets-cg/npc/char/npc_female.png
assets-cg/npc/char/npc_milkman.png
assets-cg/npc/char/npc_police.png
assets-cg/SignAction.png assets-cg/SignAction.png
assets-cg/npc/face/npc_male.png assets-cg/npc/face/npc_male.png
assets-cg/npc/face/npc_female.png assets-cg/npc/face/npc_female.png
@ -51,28 +60,15 @@ set(ASSETS_cg
assets-cg/font.png assets-cg/font.png
) )
set(ASSETS_cg_1b
assets-cg/1b/tileset/tileset1b_CG.png
)
set(ASSETS_cg_2b
assets-cg/2b/tileset/tileset2b_CG.png
)
set(ASSETS_cg_EGA64 set(ASSETS_cg_EGA64
assets-cg/ega64/tileset/tilesetEGA64_CG.png assets-cg/ega64/tileset/tilesetEGA64_CG.png
) )
set(ASSETS_fx set(ASSETS_fx
assets-fx/demo_player.png assets-fx/player_male.png
assets-fx/npc/char/npc_male.png assets-fx/player_female.png
assets-fx/SignAction.png assets-fx/SignAction.png
assets-fx/npc/face/npc_male.png
assets-fx/npc/face/npc_female.png
assets-fx/npc/face/npc_milkman.png
assets-fx/npc/face/npc_police.png
assets-fx/SGN_Icon.png assets-fx/SGN_Icon.png
assets-fx/INFO_Icon.png
assets-fx/player_face.png assets-fx/player_face.png
assets-fx/font.png assets-fx/font.png
# ... # ...
@ -80,11 +76,29 @@ set(ASSETS_fx
set(ASSETS_fx_1b set(ASSETS_fx_1b
assets-fx/1b/tileset/tileset1b.png assets-fx/1b/tileset/tileset1b.png
assets-fx/1b/npc/char/npc_male.png
assets-fx/1b/npc/char/npc_female.png
assets-fx/1b/npc/char/npc_milkman.png
assets-fx/1b/npc/char/npc_police.png
assets-fx/1b/npc/face/npc_male.png
assets-fx/1b/npc/face/npc_female.png
assets-fx/1b/npc/face/npc_milkman.png
assets-fx/1b/npc/face/npc_police.png
assets-fx/1b/INFO_Icon.png
# ... # ...
) )
set(ASSETS_fx_2b set(ASSETS_fx_2b
assets-fx/2b/tileset/tileset2b.png assets-fx/2b/tileset/tileset2b.png
assets-fx/2b/npc/char/npc_male.png
assets-fx/2b/npc/char/npc_female.png
assets-fx/2b/npc/char/npc_milkman.png
assets-fx/2b/npc/char/npc_police.png
assets-fx/2b/npc/face/npc_male.png
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
# ... # ...
) )
@ -126,26 +140,18 @@ if("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G)
elseif("${FXSDK_PLATFORM_LONG}" STREQUAL fxCG50) elseif("${FXSDK_PLATFORM_LONG}" STREQUAL fxCG50)
# cg colormode # cg colormode
if("${COLORMODE_cg}" STREQUAL 1b)
target_compile_options(myaddin PRIVATE -Wall -Wextra -Os -g -DCOLOR1BIT)
endif()
if("${COLORMODE_cg}" STREQUAL 2b)
target_compile_options(myaddin PRIVATE -Wall -Wextra -Os -g -DCOLOR2BIT)
endif()
if("${COLORMODE_cg}" STREQUAL EGA64) if("${COLORMODE_cg}" STREQUAL EGA64)
target_compile_options(myaddin PRIVATE -Wall -Wextra -O0 -g -DCOLOREGA) target_compile_options(myaddin PRIVATE -Wall -Wextra -O0 -g -DCOLOREGA)
endif() endif()
if("${COLORMODE_cg}" STREQUAL 1b) if("${COLORMODE_cg}" STREQUAL 1b)
generate_g3a(TARGET myaddin OUTPUT "RPG_1b.g3a" generate_g3a(TARGET myaddin OUTPUT "RPG_1bfx.g3a"
NAME "RPG PC 1b" ICONS assets-cg/1b/icon-uns-1b.png assets-cg/1b/icon-sel-1b.png) NAME "RPG PC 1b fx" ICONS assets-cg/1b/icon-uns-1b.png assets-cg/1b/icon-sel-1b.png)
endif() endif()
if("${COLORMODE_cg}" STREQUAL 2b) if("${COLORMODE_cg}" STREQUAL 2b)
generate_g3a(TARGET myaddin OUTPUT "RPG_2b.g3a" generate_g3a(TARGET myaddin OUTPUT "RPG_2bfx.g3a"
NAME "RPG PC 2b" ICONS assets-cg/2b/icon-uns-2b.png assets-cg/2b/icon-sel-2b.png) NAME "RPG PC 2b fx" ICONS assets-cg/2b/icon-uns-2b.png assets-cg/2b/icon-sel-2b.png)
endif() endif()
if("${COLORMODE_cg}" STREQUAL EGA64) if("${COLORMODE_cg}" STREQUAL EGA64)

View file

@ -2,32 +2,13 @@
(Mibi88) Fcalva, SlyVTT: What do you think of this? (Mibi88) Fcalva, SlyVTT: What do you think of this?
Wrap the code on 80 columns. Align the wrapped code with the last parantheses,
etc.
Use curly braces with if, else, while and for statements if they can't hold on a
single line.
Put the curly braces after if, else, while or for statements and declarations of
procedures on the same line.
No spaces around parantheses, one space after a comma.
Variables names in sneak_case. Variables names in sneak_case.
(Mibi88) SlyVTT, Fcalva, should be use a doc generation thing or do we describe Name your procedures as following: `filename_whatitdoes`.
the procedures as I did so far?
Document your procedures as following: The procedures are documented using sphinx.
```C We're using `clang-formatter` to keep the code readable. Please run it before
/* procedure_name() committing your code as following: `clang-format -i *` in the `src` folder.
*
* Describe what this procedure does.
* arg1: Describe this argument. If the text is too long, wrap it to the
* next line like this.
* long_name: Describe this argument, and so on.
*/
```
Have I forgotten something? Have I forgotten something?

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7 KiB

After

Width:  |  Height:  |  Size: 920 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 650 B

After

Width:  |  Height:  |  Size: 494 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 683 B

After

Width:  |  Height:  |  Size: 637 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 187 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

View file

@ -1,11 +1,7 @@
*.png: *.png:
custom-type: custom-image custom-type: bopti-image
name_regex: (.*)\.png \1_img name_regex: (.*)\.png \1_img
profile: p8 profile: p8
scale: 2
demo_PNG.png:
scale: 1
font.png: font.png:
name: fontRPG name: fontRPG

View file

@ -1,3 +1,15 @@
npc_male.png: npc_male.png:
type: bopti-image type: bopti-image
name: demo_PNJ_img name: tiny_npc_male
npc_female.png:
type: bopti-image
name: tiny_npc_female
npc_milkman.png:
type: bopti-image
name: tiny_npc_milkman
npc_police.png:
type: bopti-image
name: tiny_npc_police

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 167 B

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 510 B

After

Width:  |  Height:  |  Size: 808 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 494 B

After

Width:  |  Height:  |  Size: 861 B

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 544 B

After

Width:  |  Height:  |  Size: 1,000 B

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 555 B

After

Width:  |  Height:  |  Size: 992 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 246 B

BIN
assets-cg/player_female.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

BIN
assets-cg/player_male.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

BIN
assets-fx/1b/INFO_Icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 B

View file

@ -0,0 +1,3 @@
INFO_Icon.png:
type: bopti-image
name: INFO_Icon_img

View file

@ -0,0 +1,12 @@
npc_male.png:
type: bopti-image
name: tiny_npc_male
npc_female.png:
type: bopti-image
name: tiny_npc_female
npc_milkman.png:
type: bopti-image
name: tiny_npc_milkman
npc_police.png:
type: bopti-image
name: tiny_npc_police

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View file

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

View file

@ -0,0 +1,3 @@
INFO_Icon.png:
type: bopti-image
name: INFO_Icon_img

View file

@ -0,0 +1,12 @@
npc_male.png:
type: bopti-image
name: tiny_npc_male
npc_female.png:
type: bopti-image
name: tiny_npc_female
npc_milkman.png:
type: bopti-image
name: tiny_npc_milkman
npc_police.png:
type: bopti-image
name: tiny_npc_police

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 B

View file

Before

Width:  |  Height:  |  Size: 118 B

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 B

View file

@ -0,0 +1,12 @@
npc_male.png:
type: bopti-image
name: npc_male
npc_female.png:
type: bopti-image
name: npc_female
npc_milkman.png:
type: bopti-image
name: npc_milkman
npc_police.png:
type: bopti-image
name: npc_police

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 B

View file

Before

Width:  |  Height:  |  Size: 306 B

After

Width:  |  Height:  |  Size: 306 B

View file

Before

Width:  |  Height:  |  Size: 326 B

After

Width:  |  Height:  |  Size: 326 B

View file

Before

Width:  |  Height:  |  Size: 354 B

After

Width:  |  Height:  |  Size: 354 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 B

View file

@ -1,6 +1,9 @@
demo_player.png: player_male.png:
type: bopti-image type: bopti-image
name: demo_player_img name: player_male_img
player_female.png:
type: bopti-image
name: player_female_img
player_face.png: player_face.png:
type: bopti-image type: bopti-image
@ -10,10 +13,6 @@ SignAction.png:
type: bopti-image type: bopti-image
name: SignAction_img name: SignAction_img
INFO_Icon.png:
type: bopti-image
name: INFO_Icon_img
SGN_Icon.png: SGN_Icon.png:
type: bopti-image type: bopti-image
name: SGN_Icon_img name: SGN_Icon_img

View file

@ -1,3 +0,0 @@
npc_male.png:
type: bopti-image
name: demo_PNJ_img

Binary file not shown.

Before

Width:  |  Height:  |  Size: 327 B

BIN
assets-fx/player_female.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 B

View file

Before

Width:  |  Height:  |  Size: 107 B

After

Width:  |  Height:  |  Size: 107 B

37
assets/DialogsLvl4.json Normal file
View file

@ -0,0 +1,37 @@
{
"dialogs": [
{
"ID": 0,
"dialog": "Pas sur que tu trouves grand chose ici, je suis le seul ici depuis cinquante ans.",
"isQuestion": 0,
"choice": "_",
"conclusion1": "_",
"next1": -1,
"conclusion2": "_",
"next2": -1,
"nextOther": -1
},
{
"ID": 1,
"dialog": "L'eglise de Champdubouc",
"isQuestion": 0,
"choice": "_",
"conclusion1": "_",
"next1": -1,
"conclusion2": "_",
"next2": -1,
"nextOther": -1
},
{
"ID": 2,
"dialog": "Passe moi ton fric !",
"isQuestion": 0,
"choice": "_",
"conclusion1": "_",
"next1": -1,
"conclusion2": "_",
"next2": -1,
"nextOther": -1
}
]
}

View file

@ -27,6 +27,13 @@
"width": 384, "width": 384,
"x": 384, "x": 384,
"y": 192 "y": 192
},
{
"fileName": "level4.tmx",
"height": 192,
"width": 384,
"x": 384,
"y": 384
} }
], ],
"onlyShowAdjacentMaps": false, "onlyShowAdjacentMaps": false,

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.10.1" orientation="orthogonal" renderorder="right-down" width="48" height="24" tilewidth="8" tileheight="8" infinite="0" nextlayerid="5" nextobjectid="6"> <map version="1.8" tiledversion="1.8.2" orientation="orthogonal" renderorder="right-down" width="48" height="24" tilewidth="8" tileheight="8" infinite="0" nextlayerid="5" nextobjectid="6">
<properties> <properties>
<property name="dialogFile" type="file" value="DialogsLvl3.json"/> <property name="dialogFile" type="file" value="DialogsLvl3.json"/>
</properties> </properties>
@ -30,7 +30,7 @@
289,290,265,266,290,2,2,2,2,2,2,2,2,265,266,2,110,111,112,114,114,111,112,210,211,212,213,116,133,2,2,2,2,2,2,2,2,2,2,386,2,2,45,46,47,48,2,2, 289,290,265,266,290,2,2,2,2,2,2,2,2,265,266,2,110,111,112,114,114,111,112,210,211,212,213,116,133,2,2,2,2,2,2,2,2,2,2,386,2,2,45,46,47,48,2,2,
2,2,2,2,2,2,2,2,2,386,2,2,2,265,266,2,2,2,2,2,2,2,2,2,265,266,2,2,2,2,345,346,347,348,2,339,340,2,2,2,2,2,69,70,71,72,2,2, 2,2,2,2,2,2,2,2,2,386,2,2,2,265,266,2,2,2,2,2,2,2,2,2,265,266,2,2,2,2,345,346,347,348,2,339,340,2,2,2,2,2,69,70,71,72,2,2,
2,297,298,299,300,2,2,339,340,2,2,2,2,289,290,266,265,266,266,265,386,265,266,266,289,290,2,160,161,2,369,370,371,372,2,363,364,2,2,2,2,2,2,2,2,2,2,2, 2,297,298,299,300,2,2,339,340,2,2,2,2,289,290,266,265,266,266,265,386,265,266,266,289,290,2,160,161,2,369,370,371,372,2,363,364,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,386,2,2,363,364,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,385,2,393,394,395,396,2,2,2,2,2,2,2,387,2,2,2,386,2,2 2,2,2,2,386,2,2,363,364,2,2,2,2,2,2,2,2,2,2,2,265,265,2,2,2,2,2,2,385,2,393,394,395,396,2,2,2,2,2,2,2,387,2,2,2,386,2,2
</data> </data>
</layer> </layer>
<layer id="2" name="Foreground" width="48" height="24"> <layer id="2" name="Foreground" width="48" height="24">

124
assets/level4.tmx Normal file
View file

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.8" tiledversion="1.8.2" orientation="orthogonal" renderorder="right-down" width="48" height="24" tilewidth="8" tileheight="8" infinite="0" nextlayerid="6" nextobjectid="9">
<properties>
<property name="dialogFile" type="file" value="DialogsLvl4.json"/>
</properties>
<tileset firstgid="1" source="tilesetnpp.tsx"/>
<tileset firstgid="409" source="Walkable.tsx"/>
<layer id="1" name="Background" width="48" height="24">
<data encoding="csv">
385,386,6,6,385,386,385,6,6,6,6,6,6,6,6,6,385,386,385,265,266,385,386,385,386,385,121,122,123,122,123,122,124,6,6,6,6,6,6,6,6,386,6,6,6,6,6,6,
385,386,385,386,385,386,385,386,6,6,218,219,385,386,385,386,385,386,385,289,241,385,386,385,386,385,145,146,147,147,146,147,148,385,386,385,385,386,6,6,6,217,218,219,385,6,6,386,
385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,313,314,25,26,27,26,27,145,146,146,146,147,146,148,26,27,28,385,386,385,386,385,217,218,219,385,386,385,386,
385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,387,265,266,49,50,51,176,2,169,170,170,170,171,170,172,2,176,52,385,386,385,386,385,217,218,219,363,364,385,386,
385,386,385,386,176,386,385,386,385,386,385,386,385,386,385,386,385,386,385,289,290,97,98,19,50,50,121,122,59,60,61,123,124,50,50,76,385,149,150,151,152,153,154,386,176,177,178,386,
385,385,386,218,385,386,386,219,218,219,385,176,385,386,217,218,219,386,385,313,314,121,122,73,50,50,145,146,83,84,85,147,148,50,50,52,385,386,385,386,385,386,385,386,385,386,385,386,
385,386,25,26,26,26,26,26,27,28,385,386,385,386,217,218,219,386,385,265,241,14,15,49,50,177,169,170,107,108,109,171,172,50,51,52,385,387,149,150,151,152,153,154,385,217,218,219,
385,386,73,74,74,74,74,74,75,76,385,386,385,386,25,26,27,28,385,289,290,38,39,73,74,75,50,2,2,2,2,176,2,74,177,76,385,386,385,386,385,386,385,386,385,217,218,219,
385,386,97,98,98,98,98,98,99,100,385,386,385,386,73,74,75,76,385,313,314,62,63,97,98,99,98,99,98,99,98,99,98,98,99,100,385,149,150,151,152,153,154,218,219,386,385,386,
385,386,162,163,163,163,163,163,164,165,385,386,385,386,97,98,99,100,385,265,266,2,2,197,198,199,200,197,198,199,200,197,198,199,200,197,385,386,385,386,385,386,217,361,362,386,385,386,
25,26,86,87,88,89,186,187,188,189,27,26,27,26,87,88,187,188,28,241,290,160,161,221,222,223,224,221,222,223,224,221,222,223,224,221,385,386,385,386,385,386,385,386,385,386,385,386,
49,50,110,111,112,113,210,211,212,213,177,50,11,12,111,112,211,212,52,313,314,2,2,245,246,247,248,245,246,247,248,245,246,247,248,245,385,386,385,386,385,386,385,386,385,386,385,386,
73,74,75,74,75,176,234,235,236,237,75,74,35,36,75,74,74,75,76,265,266,265,266,265,266,265,266,241,266,313,314,265,266,265,266,265,241,265,266,313,314,265,266,265,266,265,266,265,
97,98,99,98,99,98,99,98,99,98,99,98,99,98,99,98,98,99,100,289,290,289,313,241,290,289,290,289,290,289,290,289,313,241,290,289,290,289,290,289,290,289,290,313,314,313,290,289,
121,122,14,15,16,17,14,15,16,17,14,15,16,17,122,59,60,61,124,265,266,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,
145,146,38,39,40,41,38,39,40,41,38,39,40,41,146,83,84,85,148,289,290,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,
169,170,62,63,64,65,62,63,64,65,62,63,64,65,170,107,108,109,172,265,266,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,
385,386,187,188,87,88,187,188,87,88,187,188,87,88,265,266,266,289,290,241,290,385,386,385,386,385,386,385,386,385,386,385,386,304,305,385,386,385,386,385,386,385,386,385,386,385,386,385,
385,386,211,212,111,112,211,212,111,112,211,212,111,112,289,290,241,313,314,313,314,176,386,385,386,217,386,385,217,218,219,217,386,328,329,385,386,176,386,217,218,219,386,385,386,385,386,385,
385,386,289,241,265,266,289,290,241,266,289,290,265,266,241,290,385,386,385,385,386,45,46,47,48,217,386,385,217,218,219,217,386,385,386,385,386,385,386,217,218,219,386,385,386,385,386,385,
385,386,313,314,289,290,241,314,289,290,313,241,289,290,313,314,385,386,385,385,386,69,70,71,72,217,386,385,217,218,219,217,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,
385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,385,386,385,386,385,386,385,304,305,386,176,386,385,386,385,386,385,386,385,386,385,386,385,386,385,217,304,305,385,
385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,385,386,385,386,385,386,385,328,329,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,217,328,329,385,
385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385
</data>
</layer>
<layer id="2" name="Foreground" width="48" height="24">
<data encoding="csv">
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,339,340,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,125,126,127,128,129,130,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,206,207,0,0,0,0,0,0,0,206,207,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,231,0,0,0,0,0,0,0,230,231,0,0,0,125,126,127,128,129,130,0,0,0,0,
0,0,0,0,0,0,0,214,215,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,254,255,0,0,0,0,0,0,0,254,255,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,238,239,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,125,126,127,128,129,130,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,337,338,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,136,137,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21,22,23,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
</data>
</layer>
<layer id="3" name="Walkable" width="48" height="24">
<data encoding="csv">
412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,0,0,412,412,412,412,412,410,410,410,410,410,410,410,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,
412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,0,0,412,412,412,412,412,410,0,0,0,0,0,410,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,
412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,0,0,410,410,410,410,410,410,0,0,0,0,0,410,410,410,410,412,412,412,412,412,412,412,412,410,410,412,412,
412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,410,0,0,410,0,0,0,0,410,0,0,0,0,0,410,0,0,410,412,412,412,412,412,412,412,412,410,410,412,412,
412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,0,0,410,0,0,0,0,410,0,410,410,410,0,410,0,0,410,412,410,410,410,410,410,410,412,412,412,412,412,
412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,0,0,410,410,0,0,0,410,0,410,0,410,0,410,0,0,410,412,412,412,412,412,412,412,412,412,412,412,412,
412,412,410,410,410,410,410,410,410,410,412,412,412,412,412,412,412,412,412,0,0,0,0,0,410,410,410,410,410,0,410,410,410,410,410,410,412,410,410,410,410,410,410,410,412,412,412,412,
412,412,410,0,0,0,0,0,0,410,412,412,412,412,410,410,410,410,412,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,412,412,412,412,412,412,412,412,412,412,412,412,
412,412,410,0,0,0,0,0,0,410,412,412,412,412,410,0,0,410,412,0,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,410,412,410,410,410,410,410,410,410,410,412,412,412,
412,412,410,0,0,0,410,410,410,410,412,412,412,412,410,410,410,410,412,0,0,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,412,412,412,412,412,412,412,410,410,412,412,412,
410,410,410,0,0,0,410,0,0,410,410,410,410,410,410,410,0,0,410,0,0,410,410,410,0,0,0,0,0,0,0,0,0,0,0,410,412,412,412,412,412,412,412,412,412,412,412,412,
410,0,410,410,410,410,410,0,0,410,0,0,0,0,410,410,0,0,410,0,0,0,0,410,410,410,410,410,410,410,410,410,410,410,410,410,412,412,412,412,412,412,412,412,412,412,412,412,
410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,0,0,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,
410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,0,410,410,0,0,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,
410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,0,410,410,0,0,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,
412,412,0,0,410,410,0,0,410,410,0,0,410,410,0,0,0,0,0,0,0,412,412,412,412,412,412,412,412,412,412,412,412,410,410,412,412,412,412,412,412,412,412,412,412,412,412,412,
412,412,0,0,410,410,0,0,410,410,0,0,410,410,0,0,0,0,0,0,0,410,410,410,410,412,412,412,412,412,412,412,412,410,410,412,412,412,412,412,412,412,412,412,412,412,412,412,
412,412,0,0,0,0,0,0,0,0,0,0,0,0,0,0,412,412,412,412,412,410,410,410,410,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,
412,412,0,0,0,0,0,0,0,0,0,0,0,0,0,0,412,412,412,412,412,410,410,410,410,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,
412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,410,410,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,410,410,412,
412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,410,410,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,410,410,412,
412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412
</data>
</layer>
<objectgroup id="4" name="ExtraData">
<object id="3" name="SGN1" type="SGN" x="176.852" y="88.7417">
<properties>
<property name="dialogID" type="int" value="1"/>
<property name="needAction" type="int" value="1"/>
</properties>
<point/>
</object>
<object id="6" name="NPC1" type="NPC" x="147.952" y="62.6849">
<properties>
<property name="dialogID" type="int" value="0"/>
<property name="face" value="MAN"/>
<property name="hasPath" type="int" value="1"/>
<property name="needAction" type="int" value="1"/>
<property name="path" type="object" value="8"/>
</properties>
<point/>
</object>
<object id="7" name="ENEMY1" type="NPC" x="182.215" y="181.047">
<properties>
<property name="dialogID" type="int" value="2"/>
<property name="face" value="MALE"/>
<property name="hasPath" type="int" value="0"/>
<property name="needAction" type="int" value="1"/>
<property name="path" type="object" value="0"/>
</properties>
<point/>
</object>
<object id="8" name="CHEMIN_FERMIER" x="147.952" y="63.0743">
<polyline points="0,0 13.6272,31.1478 50.6152,79.4269 13.6272,74.7547 -7.3976,102.009 -15.5739,71.6399 -17.91,116.804 47.8897,112.132 71.6399,87.2138 131.21,112.132 176.374,91.1073 218.424,89.9393 131.599,59.1808 74.3654,64.2423 50.2258,44.775 29.9798,42.4389 3.50413,3.50413"/>
</object>
</objectgroup>
</map>

View file

@ -1,7 +1,6 @@
#ifndef CONFIG_H #ifndef CONFIG_H
#define CONFIG_H #define CONFIG_H
#define USB_FEATURE 0 #define USB_FEATURE 0
#define DEBUGMODE 1 #define DEBUGMODE 1
@ -12,8 +11,6 @@
#define GRAYMODEOK 1 #define GRAYMODEOK 1
#endif #endif
#if GINT_RENDER_RGB #if GINT_RENDER_RGB
/* The tile size */ /* The tile size */
#define T_HEIGHT 16 #define T_HEIGHT 16
@ -36,7 +33,6 @@
#define P_HEIGHT 8 #define P_HEIGHT 8
#endif #endif
/* SPEED should NOT be 8 or bigger: it may cause bugs when handling /* SPEED should NOT be 8 or bigger: it may cause bugs when handling
* collisions! */ * collisions! */
#define SPEED (PXSIZE * 2) #define SPEED (PXSIZE * 2)

View file

@ -1,22 +1,19 @@
#include "dialogs.h" #include "dialogs.h"
#include <gint/keyboard.h>
#include <gint/cpu.h>
#include <string.h>
#include "config.h" #include "config.h"
#include "events.h"
#include "game.h" #include "game.h"
#include "npc.h" #include "npc.h"
#include "events.h"
#include <gint/cpu.h>
#include <gint/keyboard.h>
#include <string.h>
#define BOX_HEIGHT (F_HEIGHT / PXSIZE + 8) #define BOX_HEIGHT (F_HEIGHT / PXSIZE + 8)
#define CHOICE_BOX_HEIGHT 10 #define CHOICE_BOX_HEIGHT 10
#define CHOICE_BOX_PADDING_TOP 3 #define CHOICE_BOX_PADDING_TOP 3
extern font_t fontRPG; extern font_t fontRPG;
#define FONT_USED fontRPG #define FONT_USED fontRPG
@ -26,7 +23,6 @@ extern font_t fontRPG;
uint32_t *lightVRAMcurrent, *darkVRAMcurrent; uint32_t *lightVRAMcurrent, *darkVRAMcurrent;
#endif // GRAYMODEOK #endif // GRAYMODEOK
void blit() { void blit() {
dupdate(); dupdate();
@ -39,20 +35,18 @@ void blit() {
#endif #endif
} }
int dialogs_text_opt(Game *game, bopti_image_t *face, char *text, int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
int call_before_end(Game *game, unsigned int i), int call_before_end(Game *game, unsigned int i),
bool start_anim, bool start_anim, bool end_anim,
bool end_anim,
void for_each_screen(Game *game, unsigned int i), void for_each_screen(Game *game, unsigned int i),
int line_duration, bool update_screen, unsigned int start_i, int line_duration, bool update_screen,
bool wait_continue) { unsigned int start_i, bool wait_continue) {
text = events_parse_string(&game->handler, text); text = events_parse_string(&game->handler, text);
dfont(&FONT_USED); dfont(&FONT_USED);
unsigned int i, n, y = PXSIZE, l = 0; unsigned int i, n, y = PXSIZE, l = 0;
int line_max_chars, return_int = 0; int line_max_chars, return_int = 0;
unsigned int max_lines_amount = (BOX_HEIGHT-2)*PXSIZE/ unsigned int max_lines_amount =
(FONT_USED.line_height+PXSIZE); (BOX_HEIGHT - 2) * PXSIZE / (FONT_USED.line_height + PXSIZE);
const char *c; const char *c;
if(start_anim) { if(start_anim) {
/* Run a little fancy animation. */ /* Run a little fancy animation. */
@ -69,12 +63,13 @@ int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
/* Draw the part of the face of the player that can fit correctly in /* Draw the part of the face of the player that can fit correctly in
* the dialog drawn. */ * the dialog drawn. */
dsubimage(4*PXSIZE, 2*PXSIZE, face, 0, 0, F_WIDTH, (i-8)*PXSIZE, dsubimage(4 * PXSIZE, 2 * PXSIZE, face, 0, 0, F_WIDTH,
DIMAGE_NONE); (i - 8) * PXSIZE, DIMAGE_NONE);
blit(); blit();
while(game->frame_duration < 20) sleep(); while(game->frame_duration < 20)
sleep();
game->frame_duration = 0; game->frame_duration = 0;
} }
} else { } else {
@ -82,23 +77,27 @@ int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
* making an animation. */ * making an animation. */
game_draw(game); game_draw(game);
drect(0, 0, DWIDTH, BOX_HEIGHT * PXSIZE, C_WHITE); drect(0, 0, DWIDTH, BOX_HEIGHT * PXSIZE, C_WHITE);
drect(0, BOX_HEIGHT*PXSIZE, DWIDTH, (BOX_HEIGHT+1)*PXSIZE, C_BLACK); drect(0, BOX_HEIGHT * PXSIZE, DWIDTH, (BOX_HEIGHT + 1) * PXSIZE,
C_BLACK);
dimage(4 * PXSIZE, 2 * PXSIZE, face); dimage(4 * PXSIZE, 2 * PXSIZE, face);
if(update_screen) { if(update_screen) {
blit(); blit();
while(game->frame_duration < 20) sleep(); while(game->frame_duration < 20)
sleep();
game->frame_duration = 0; game->frame_duration = 0;
} }
} }
/* We should start to drawing the text on the x axis at BOX_HEIGHT to avoid /* We should start to drawing the text on the x axis at BOX_HEIGHT to avoid
* drawing on the face. */ * drawing on the face. */
for(i = start_i; i < strlen(text); i++) { for(i = start_i; i < strlen(text); i++) {
if(!l && for_each_screen) for_each_screen(game, i); if(!l && for_each_screen)
for_each_screen(game, i);
/* Get how many chars we can draw on screen with a padding on the left /* Get how many chars we can draw on screen with a padding on the left
* of BOX_HEIGHT px and on the right of 1 px. */ * of BOX_HEIGHT px and on the right of 1 px. */
c = drsize(text+i, &FONT_USED, DWIDTH-(BOX_HEIGHT*PXSIZE+PXSIZE), NULL); c = drsize(text + i, &FONT_USED,
DWIDTH - (BOX_HEIGHT * PXSIZE + PXSIZE), NULL);
/* c is a pointer to the last char that can be drawn. So: */ /* c is a pointer to the last char that can be drawn. So: */
line_max_chars = c - (text + i); line_max_chars = c - (text + i);
/* TODO: Handle lines that are longer than what I can draw and '\n'. */ /* TODO: Handle lines that are longer than what I can draw and '\n'. */
@ -109,8 +108,9 @@ int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
/* If we found a space, we can draw this line and do the same /* If we found a space, we can draw this line and do the same
* for the next line. */ * for the next line. */
if(text[i + n] == ' ') { if(text[i + n] == ' ') {
dtext_opt(BOX_HEIGHT*PXSIZE, y, C_BLACK, C_NONE, DTEXT_LEFT, dtext_opt(BOX_HEIGHT * PXSIZE, y, C_BLACK, C_NONE,
DTEXT_TOP, text+i, n); /* Draw everything. */ DTEXT_LEFT, DTEXT_TOP, text + i,
n); /* Draw everything. */
/* Increment y by the line height. */ /* Increment y by the line height. */
y += FONT_USED.line_height + PXSIZE; y += FONT_USED.line_height + PXSIZE;
i += n; /* We drew everything to i+n */ i += n; /* We drew everything to i+n */
@ -130,20 +130,25 @@ int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
/* We drew one entire screen, reset everything to draw the next one. /* We drew one entire screen, reset everything to draw the next one.
*/ */
/* Make a little animation :). */ /* Make a little animation :). */
if(update_screen) blit(); if(update_screen)
while(game->frame_duration < line_duration) sleep(); blit();
while(game->frame_duration < line_duration)
sleep();
game->frame_duration = 0; game->frame_duration = 0;
/* Ask the user to press SHIFT to continue. */ /* Ask the user to press SHIFT to continue. */
dtext(BOX_HEIGHT * PXSIZE, y, NEXT_COLOR, "[SHIFT] : suite..."); dtext(BOX_HEIGHT * PXSIZE, y, NEXT_COLOR, "[SHIFT] : suite...");
} }
/* Make a little animation :). */ /* Make a little animation :). */
if(update_screen) blit(); if(update_screen)
blit();
if(l >= max_lines_amount - 1) { if(l >= max_lines_amount - 1) {
/* If we drew one entire screen. */ /* If we drew one entire screen. */
/* Wait that the SHIFT key is pressed if we should. */ /* Wait that the SHIFT key is pressed if we should. */
if(wait_continue) { if(wait_continue) {
while(getkey_opt(GETKEY_DEFAULT & ~GETKEY_MOD_SHIFT & while(getkey_opt(GETKEY_DEFAULT & ~GETKEY_MOD_SHIFT &
~GETKEY_MOD_ALPHA, NULL).key != KEY_SHIFT){ ~GETKEY_MOD_ALPHA,
NULL)
.key != KEY_SHIFT) {
sleep(); sleep();
} }
} }
@ -153,31 +158,37 @@ int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
/* Reset y and l. */ /* Reset y and l. */
y = PXSIZE; y = PXSIZE;
l = 0; l = 0;
} } else {
else{
/* Else, wait a bit for the animation. */ /* Else, wait a bit for the animation. */
while(game->frame_duration < line_duration) sleep(); while(game->frame_duration < line_duration)
sleep();
game->frame_duration = 0; game->frame_duration = 0;
} }
} }
if(l < max_lines_amount - 1) { if(l < max_lines_amount - 1) {
/* If we have not filled everthing with text at the end. */ /* If we have not filled everthing with text at the end. */
/* Make a little animation :). */ /* Make a little animation :). */
if(update_screen) blit(); if(update_screen)
while(game->frame_duration < line_duration) sleep(); blit();
while(game->frame_duration < line_duration)
sleep();
game->frame_duration = 0; game->frame_duration = 0;
/* Ask the user to press SHIFT to continue. */ /* Ask the user to press SHIFT to continue. */
dtext(BOX_HEIGHT * PXSIZE, y, NEXT_COLOR, "[SHIFT] : suite..."); dtext(BOX_HEIGHT * PXSIZE, y, NEXT_COLOR, "[SHIFT] : suite...");
/* Update the screen and wait for SHIFT being pressed, if needed. */ /* Update the screen and wait for SHIFT being pressed, if needed. */
if(update_screen) blit(); if(update_screen)
blit();
if(wait_continue) { if(wait_continue) {
while(getkey_opt(GETKEY_DEFAULT & ~GETKEY_MOD_SHIFT & while(getkey_opt(GETKEY_DEFAULT & ~GETKEY_MOD_SHIFT &
~GETKEY_MOD_ALPHA, NULL).key != KEY_SHIFT){ ~GETKEY_MOD_ALPHA,
NULL)
.key != KEY_SHIFT) {
sleep(); sleep();
} }
} }
} }
if(call_before_end) return_int = call_before_end(game, i); if(call_before_end)
return_int = call_before_end(game, i);
if(end_anim) { if(end_anim) {
/* Run another little fancy animation if we should. */ /* Run another little fancy animation if we should. */
for(i = BOX_HEIGHT; i > 0; i--) { for(i = BOX_HEIGHT; i > 0; i--) {
@ -186,12 +197,13 @@ int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
game_draw(game); game_draw(game);
drect(0, 0, DWIDTH, i * PXSIZE, C_WHITE); drect(0, 0, DWIDTH, i * PXSIZE, C_WHITE);
drect(0, i * PXSIZE, DWIDTH, (i + 1) * PXSIZE, C_BLACK); drect(0, i * PXSIZE, DWIDTH, (i + 1) * PXSIZE, C_BLACK);
dsubimage(4*PXSIZE, 2*PXSIZE, face, 0, 0, F_WIDTH, (i-8)*PXSIZE, dsubimage(4 * PXSIZE, 2 * PXSIZE, face, 0, 0, F_WIDTH,
DIMAGE_NONE); (i - 8) * PXSIZE, DIMAGE_NONE);
dupdate(); dupdate();
while(game->frame_duration < 20) sleep(); while(game->frame_duration < 20)
sleep();
game->frame_duration = 0; game->frame_duration = 0;
} }
} }
@ -202,11 +214,10 @@ void dialogs_text(Game *game, bopti_image_t *face, char *text,
bool dialog_start, bool dialog_end) { bool dialog_start, bool dialog_end) {
/* Run showtext_opt with some default values. It makes it easier to use in /* Run showtext_opt with some default values. It makes it easier to use in
* simple dialogs. */ * simple dialogs. */
dialogs_text_opt(game, face, text, NULL, dialog_start, dialog_end, NULL, 100, dialogs_text_opt(game, face, text, NULL, dialog_start, dialog_end, NULL,
true, 0, true); 100, true, 0, true);
} }
/* Some variables and pointers used to get some arguments passed in /* Some variables and pointers used to get some arguments passed in
* showtext_dialog_ask in _choice_call_before_end. */ * showtext_dialog_ask in _choice_call_before_end. */
char *_choices, *_text; char *_choices, *_text;
@ -228,7 +239,8 @@ int _choice_call_before_end(Game *game, [[maybe_unused]] unsigned int org_i) {
drect(0, (BOX_HEIGHT + 1) * PXSIZE + 1, i * (DWIDTH / 8), drect(0, (BOX_HEIGHT + 1) * PXSIZE + 1, i * (DWIDTH / 8),
(BOX_HEIGHT + CHOICE_BOX_HEIGHT) * PXSIZE, C_WHITE); (BOX_HEIGHT + CHOICE_BOX_HEIGHT) * PXSIZE, C_WHITE);
/* Draw a thick border on the right of the box. */ /* Draw a thick border on the right of the box. */
drect(i*(DWIDTH/8), BOX_HEIGHT*PXSIZE, i*(DWIDTH/8)+PXSIZE-1, drect(i * (DWIDTH / 8), BOX_HEIGHT * PXSIZE,
i * (DWIDTH / 8) + PXSIZE - 1,
(BOX_HEIGHT + CHOICE_BOX_HEIGHT + 1) * PXSIZE, C_BLACK); (BOX_HEIGHT + CHOICE_BOX_HEIGHT + 1) * PXSIZE, C_BLACK);
/* Draw a thick border on the bottom of the box. */ /* Draw a thick border on the bottom of the box. */
drect(0, (BOX_HEIGHT + CHOICE_BOX_HEIGHT) * PXSIZE, i * (DWIDTH / 8), drect(0, (BOX_HEIGHT + CHOICE_BOX_HEIGHT) * PXSIZE, i * (DWIDTH / 8),
@ -236,7 +248,8 @@ int _choice_call_before_end(Game *game, [[maybe_unused]] unsigned int org_i) {
/* Show everyting on screen. */ /* Show everyting on screen. */
blit(); blit();
/* Wait some ms so that the animation isn't too fast. */ /* Wait some ms so that the animation isn't too fast. */
while(game->frame_duration < 20) sleep(); while(game->frame_duration < 20)
sleep();
game->frame_duration = 0; game->frame_duration = 0;
} }
/* Calculate the maximal size of a choice. */ /* Calculate the maximal size of a choice. */
@ -265,12 +278,15 @@ int _choice_call_before_end(Game *game, [[maybe_unused]] unsigned int org_i) {
do { do {
/* Display the diffrent choices. */ /* Display the diffrent choices. */
for(i = 0; i < _choices_amount; i++) { for(i = 0; i < _choices_amount; i++) {
if(i == selected) dtext(i*choice_size+PXSIZE, if(i == selected)
(BOX_HEIGHT+CHOICE_BOX_PADDING_TOP)*PXSIZE, dtext(i * choice_size + PXSIZE,
C_BLACK, ">"); (BOX_HEIGHT + CHOICE_BOX_PADDING_TOP) * PXSIZE, C_BLACK,
">");
} }
blit(); blit();
key = getkey_opt( GETKEY_DEFAULT & ~GETKEY_MOD_SHIFT & ~GETKEY_MOD_ALPHA, NULL).key; key = getkey_opt(GETKEY_DEFAULT & ~GETKEY_MOD_SHIFT & ~GETKEY_MOD_ALPHA,
NULL)
.key;
/* If the player pressed the left arrow key and has not already selected /* If the player pressed the left arrow key and has not already selected
* the first possible choice. */ * the first possible choice. */
if(key == KEY_LEFT && selected > 0) { if(key == KEY_LEFT && selected > 0) {
@ -297,8 +313,8 @@ int _choice_call_before_end(Game *game, [[maybe_unused]] unsigned int org_i) {
/* Move the selection arrow and update the selected item. */ /* Move the selection arrow and update the selected item. */
selected++; selected++;
} }
/* If the user has not validated his choice by pressing SHIFT, we loop one /* If the user has not validated his choice by pressing SHIFT, we loop
* more time. */ * one more time. */
} while(key != KEY_SHIFT); } while(key != KEY_SHIFT);
/* Make a little animation because we looove little animations ;) */ /* Make a little animation because we looove little animations ;) */
for(i = DWIDTH / 8 + 1; i > 0; i--) { for(i = DWIDTH / 8 + 1; i > 0; i--) {
@ -309,12 +325,14 @@ int _choice_call_before_end(Game *game, [[maybe_unused]] unsigned int org_i) {
_i, false); _i, false);
drect(0, (BOX_HEIGHT + 1) * PXSIZE + 1, i * (DWIDTH / 8), drect(0, (BOX_HEIGHT + 1) * PXSIZE + 1, i * (DWIDTH / 8),
(BOX_HEIGHT + CHOICE_BOX_HEIGHT) * PXSIZE, C_WHITE); (BOX_HEIGHT + CHOICE_BOX_HEIGHT) * PXSIZE, C_WHITE);
drect(i*(DWIDTH/8), BOX_HEIGHT*PXSIZE, i*(DWIDTH/8)+PXSIZE-1, drect(i * (DWIDTH / 8), BOX_HEIGHT * PXSIZE,
i * (DWIDTH / 8) + PXSIZE - 1,
(BOX_HEIGHT + CHOICE_BOX_HEIGHT + 1) * PXSIZE, C_BLACK); (BOX_HEIGHT + CHOICE_BOX_HEIGHT + 1) * PXSIZE, C_BLACK);
drect(0, (BOX_HEIGHT + CHOICE_BOX_HEIGHT) * PXSIZE, i * (DWIDTH / 8), drect(0, (BOX_HEIGHT + CHOICE_BOX_HEIGHT) * PXSIZE, i * (DWIDTH / 8),
(BOX_HEIGHT + CHOICE_BOX_HEIGHT + 1) * PXSIZE, C_BLACK); (BOX_HEIGHT + CHOICE_BOX_HEIGHT + 1) * PXSIZE, C_BLACK);
dupdate(); dupdate();
while(game->frame_duration < 20) sleep(); while(game->frame_duration < 20)
sleep();
game->frame_duration = 0; game->frame_duration = 0;
} }
/* Return the selected item because he'll also be returned by showtext_opt. /* Return the selected item because he'll also be returned by showtext_opt.
@ -338,9 +356,6 @@ int dialogs_ask(Game *game, bopti_image_t *face, char *text, bool start,
end, _choice_screen_call, 100, true, 0, true); end, _choice_screen_call, 100, true, 0, true);
} }
void dialogs_initiate_sequence(Game *game, bopti_image_t *face, void dialogs_initiate_sequence(Game *game, bopti_image_t *face,
uint32_t dialogNumber) { uint32_t dialogNumber) {
Dialog *currentDiag = &game->map_level->dialogs[dialogNumber]; Dialog *currentDiag = &game->map_level->dialogs[dialogNumber];
@ -359,21 +374,23 @@ void dialogs_initiate_sequence(Game *game, bopti_image_t *face,
/* we treat the action - i.e. we show a dialog */ /* we treat the action - i.e. we show a dialog */
if(isQuestion == 1) { if(isQuestion == 1) {
/* we have to manage a question */ /* we have to manage a question */
int answer = dialogs_ask(game, face, text, true, true, int answer = dialogs_ask(game, face, text, true, true, choices, 2, 0);
choices, 2, 0);
/* TO DO we need to split the strings conclusion1 and conclusion2 */ /* TO DO we need to split the strings conclusion1 and conclusion2 */
/* to extract the "gift" part */ /* to extract the "gift" part */
if(answer == 0) { if(answer == 0) {
dialogs_text(game, face, conclusion1, true, true); dialogs_text(game, face, conclusion1, true, true);
if (next1!=-1) dialogs_initiate_sequence(game, face, next1); if(next1 != -1)
dialogs_initiate_sequence(game, face, next1);
} else { } else {
dialogs_text(game, face, conclusion2, true, true); dialogs_text(game, face, conclusion2, true, true);
if (next2!=-1) dialogs_initiate_sequence(game, face, next2); if(next2 != -1)
dialogs_initiate_sequence(game, face, next2);
} }
} else { } else {
dialogs_text(game, face, text, true, true); dialogs_text(game, face, text, true, true);
if (nextOther!=-1) dialogs_initiate_sequence(game, face, nextOther); if(nextOther != -1)
dialogs_initiate_sequence(game, face, nextOther);
} }
} }

View file

@ -1,11 +1,12 @@
#ifndef DIALOG_H #ifndef DIALOG_H
#define DIALOG_H #define DIALOG_H
#include <gint/display.h> #include "config.h"
#include <string.h>
#include "game.h" #include "game.h"
#include "map.h" #include "map.h"
#include "config.h"
#include <gint/display.h>
#include <string.h>
/* dialogs_text_opt() /* dialogs_text_opt()
* *
@ -37,8 +38,7 @@
int dialogs_text_opt(Game *game, bopti_image_t *face, char *text, int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
int call_before_end(Game *game, unsigned int i), int call_before_end(Game *game, unsigned int i),
bool start_anim, bool start_anim, bool end_anim,
bool end_anim,
void for_each_screen(Game *game, unsigned int i), void for_each_screen(Game *game, unsigned int i),
int line_duration, bool update_screen, int line_duration, bool update_screen,
unsigned int start_i, bool wait_continue); unsigned int start_i, bool wait_continue);

View file

@ -1,10 +1,9 @@
#include <stdlib.h>
#include <string.h>
#include "events.h" #include "events.h"
void events_init_handler(EventHandler *handler) { #include <stdlib.h>
handler->vars = 0; #include <string.h>
}
void events_init_handler(EventHandler *handler) { handler->vars = 0; }
int events_bind_variable(EventHandler *handler, int *var, char *name) { int events_bind_variable(EventHandler *handler, int *var, char *name) {
if(handler->vars < MAX_VARIABLES) { if(handler->vars < MAX_VARIABLES) {
@ -18,45 +17,30 @@ int events_bind_variable(EventHandler *handler, int *var, char *name) {
char op_chars[OP_AMOUNT + 1] = " =+-/*%"; char op_chars[OP_AMOUNT + 1] = " =+-/*%";
int _op_null(int a, int b) { int _op_null(int a, int b) { return 0; }
return 0;
}
int _op_set(int a, int b) { int _op_set(int a, int b) { return b; }
return b;
}
int _op_add(int a, int b) { int _op_add(int a, int b) { return a + b; }
return a+b;
}
int _op_sub(int a, int b) { int _op_sub(int a, int b) { return a - b; }
return a-b;
}
int _op_div(int a, int b) { int _op_div(int a, int b) {
if(b == 0) return 0; if(b == 0)
return 0;
return a / b; return a / b;
} }
int _op_mul(int a, int b) { int _op_mul(int a, int b) { return a * b; }
return a*b;
}
int _op_mod(int a, int b) { int _op_mod(int a, int b) {
if(b == 0) return 0; if(b == 0)
return 0;
return a % b; return a % b;
} }
int (*_operations[OP_AMOUNT])(int, int) = { int (*_operations[OP_AMOUNT])(int, int) = {_op_null, _op_set, _op_add, _op_sub,
_op_null, _op_div, _op_mul, _op_mod};
_op_set,
_op_add,
_op_sub,
_op_div,
_op_mul,
_op_mod
};
#define MIN(a, b) a < b ? a : b #define MIN(a, b) a < b ? a : b
@ -99,18 +83,21 @@ char *events_parse_string(EventHandler *handler, char *message) {
num_pos = 0; num_pos = 0;
} }
} else if(!in_token) { } else if(!in_token) {
if(message_pos < TOKEN_MAX_SZ) _message_buffer[message_pos++] = c; if(message_pos < TOKEN_MAX_SZ)
_message_buffer[message_pos++] = c;
} }
if(in_token && c != ' ') { if(in_token && c != ' ') {
if(tok_type == T_VAR_EDIT) { if(tok_type == T_VAR_EDIT) {
if(var_op != OP_NULL) { if(var_op != OP_NULL) {
if(num_pos < TOKEN_MAX_SZ) num[num_pos++] = c; if(num_pos < TOKEN_MAX_SZ)
num[num_pos++] = c;
} }
if(strchr(op_chars, c)) { if(strchr(op_chars, c)) {
var_op = (Operation)(strchr(op_chars, c) - op_chars); var_op = (Operation)(strchr(op_chars, c) - op_chars);
} }
if(var_op == OP_NULL) { if(var_op == OP_NULL) {
if(name_pos < TOKEN_MAX_SZ) var_name[name_pos++] = c; if(name_pos < TOKEN_MAX_SZ)
var_name[name_pos++] = c;
} }
} }
if(c == '$') { if(c == '$') {

View file

@ -15,11 +15,7 @@ typedef struct {
unsigned int vars; unsigned int vars;
} EventHandler; } EventHandler;
typedef enum { typedef enum { T_NULL, T_VAR_EDIT, T_AMOUNT } Token;
T_NULL,
T_VAR_EDIT,
T_AMOUNT
} Token;
typedef enum { typedef enum {
OP_NULL, OP_NULL,

View file

@ -1,17 +1,14 @@
#include "game.h" #include "game.h"
#include "map.h"
#include "config.h" #include "config.h"
#include "map.h"
#include <stdlib.h>
#include <string.h>
#include <gint/keyboard.h>
#include <gint/cpu.h>
#include <gint/display.h>
#include "npc.h" #include "npc.h"
#include <gint/cpu.h>
#include <gint/display.h>
#include <gint/keyboard.h>
#include <stdlib.h>
#include <string.h>
extern bopti_image_t SignAction_img; extern bopti_image_t SignAction_img;
@ -87,13 +84,13 @@ void game_logic(Game *game) {
void game_render_indicator(Game *game) { void game_render_indicator(Game *game) {
/* nothing to do for the player so we quit */ /* nothing to do for the player so we quit */
if(game->player.canDoSomething==false) return; if(game->player.canDoSomething == false)
return;
/* else we draw a small indicator on the screen */ /* else we draw a small indicator on the screen */
dimage(5, 5, &SignAction_img); dimage(5, 5, &SignAction_img);
} }
void game_draw(Game *game) { void game_draw(Game *game) {
/* Draw everything. */ /* Draw everything. */
dclear(C_WHITE); dclear(C_WHITE);
@ -116,14 +113,28 @@ void game_get_inputs(Game *game) {
/*************************************/ /*************************************/
if(keydown(KEY_EXIT)) game->exittoOS = true; if(keydown(KEY_EXIT))
game->exittoOS = true;
/* Player actions - Prototypes in player.h and implementation in player.c */ /* Player actions - Prototypes in player.h and implementation in player.c */
if(keydown(KEY_LEFT)) player_move(game, D_LEFT); if(keydown(KEY_LEFT))
if(keydown(KEY_RIGHT)) player_move(game, D_RIGHT); player_move(game, D_LEFT);
if(keydown(KEY_UP)) player_move(game, D_UP); if(keydown(KEY_RIGHT))
if(keydown(KEY_DOWN)) player_move(game, D_DOWN); player_move(game, D_RIGHT);
if(keydown(KEY_SHIFT)) player_action(game); 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();
}
}
/* Display Debug Information on screen */ /* Display Debug Information on screen */
#if DEBUGMODE #if DEBUGMODE
@ -138,12 +149,13 @@ void game_get_inputs(Game *game) {
} }
#endif #endif
/* if USB is enabled - keybinding for screencapture */ /* if USB is enabled - keybinding for screencapture */
#if USB_FEATURE #if USB_FEATURE
if(keydown(KEY_7)) game->screenshot = true; if(keydown(KEY_7))
if(keydown(KEY_8)) game->record = !game->record; game->screenshot = true;
if(keydown(KEY_8))
game->record = !game->record;
#endif // USB_FEATURE #endif // USB_FEATURE
} }

View file

@ -1,21 +1,13 @@
#ifndef GAME_H #ifndef GAME_H
#define GAME_H #define GAME_H
#include "events.h"
#include <gint/display.h> #include <gint/display.h>
#include <stdint.h> #include <stdint.h>
#include "events.h"
/* The direction where the player is going to. */ /* The direction where the player is going to. */
typedef enum { typedef enum { D_UP, D_DOWN, D_LEFT, D_RIGHT } Direction;
D_UP,
D_DOWN,
D_LEFT,
D_RIGHT
} Direction;
typedef enum { typedef enum {
P_LEFTUP = -1, P_LEFTUP = -1,
@ -38,7 +30,6 @@ typedef struct {
int8_t life; /* How many lives the player still has between 0 and 100. */ int8_t life; /* How many lives the player still has between 0 and 100. */
int8_t speed; /* The speed of the movement of the player. */ int8_t speed; /* The speed of the movement of the player. */
/* set to true if a action can be done in the current position of the map */ /* set to true if a action can be done in the current position of the map */
bool canDoSomething; bool canDoSomething;
/* indicates which data are relevant to the current action in the */ /* indicates which data are relevant to the current action in the */
@ -48,9 +39,9 @@ typedef struct {
bool isDoingAction; bool isDoingAction;
/* the player is interacting with a NPC */ /* the player is interacting with a NPC */
bool isInteractingWithNPC; bool isInteractingWithNPC;
bool is_male;
} Player; } Player;
typedef struct { typedef struct {
uint32_t ID; uint32_t ID;
/* data to be shown in the dialog*/ /* data to be shown in the dialog*/
@ -68,8 +59,8 @@ typedef struct {
int32_t nextOther; int32_t nextOther;
} Dialog; } Dialog;
typedef struct typedef struct {
{ /* position of the item */
uint32_t x; uint32_t x;
uint32_t y; uint32_t y;
/*id of it's icon*/ /*id of it's icon*/
@ -82,7 +73,6 @@ typedef struct
uint32_t dialogID; uint32_t dialogID;
/*if the dialog is interactive or not*/ /*if the dialog is interactive or not*/
uint32_t needAction; uint32_t needAction;
} Sign; } Sign;
typedef struct typedef struct
@ -120,17 +110,14 @@ typedef struct
uint8_t hostile_to_group; uint8_t hostile_to_group;
uint16_t __padding; uint16_t __padding;
} NPC; } NPC;
typedef struct{ typedef struct{
Collider collider; Collider collider;
/*if the portal tps to an interior or exterior map*/ /*if the portal tps to an interior or exterior map*/
uint16_t tp_interior; uint16_t tp_interior;
/*Id of the interior/exterior map to transport the player to*/ /*Id of the interior/exterior map to transport the player to*/
uint16_t tp_to; uint16_t tp_to;
} Portal; } Portal;
typedef struct { typedef struct {
@ -172,8 +159,6 @@ typedef struct {
} Map; } Map;
/* This struct will contain all the data of the game. It will make it possible /* This struct will contain all the data of the game. It will make it possible
* to pass it to the NPCs to let them interact with the player and the rest of * to pass it to the NPCs to let them interact with the player and the rest of
* the world. */ * the world. */
@ -225,4 +210,3 @@ void game_render_indicator(Game *game);
void game_get_inputs(Game *game); void game_get_inputs(Game *game);
#endif #endif

View file

@ -3,18 +3,14 @@
#include <gint/timer.h> #include <gint/timer.h>
#include <gint/cpu.h> #include <gint/cpu.h>
#include <fxlibc/printf.h>
#include "config.h" #include "config.h"
#include "npc.h"
#include "events.h"
#if USB_FEATURE #if USB_FEATURE
#include <gint/usb-ff-bulk.h> #include <gint/usb-ff-bulk.h>
#include <gint/usb.h> #include <gint/usb.h>
#endif // USB_FEATURE #endif // USB_FEATURE
#if GRAYMODEOK #if GRAYMODEOK
#include <gint/gray.h> #include <gint/gray.h>
#endif //GRAYMODEOK #endif //GRAYMODEOK
@ -23,36 +19,41 @@
#include <gint/gdb.h> #include <gint/gdb.h>
#endif /*DEBUGMODE*/ #endif /*DEBUGMODE*/
#include <stdint.h> #include "dialogs.h"
#include <stdbool.h>
#include "game.h" #include "game.h"
#include "mapdata.h" #include "mapdata.h"
#include "dialogs.h" #include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
extern bopti_image_t player_face_img; extern bopti_image_t player_face_img;
extern Map *worldRPG[]; extern Map *worldRPG[];
/* Game data (defined in "game.h")*/ /* Game data (defined in "game.h")*/
Game game = { Game game = {NULL,
NULL, {12 * PXSIZE, 36 * PXSIZE, 0, 0, 12 * PXSIZE, 36 * PXSIZE, 100,
{12*PXSIZE, 36*PXSIZE, 0, 0, 12*PXSIZE, 36*PXSIZE, 100, SPEED, false, 0, false, false}, SPEED, false, 0, false, false, true, true},
{{}, {}, 0}, {{}, {}, 0},
false, false, false, 0 false,
false,
false,
0
/* debug variables*/ /* debug variables*/
, false, false, false, 100 ,
}; false,
false,
false,
100};
/* screen capture management code. TODO: Clean this up! */ /* screen capture management code. TODO: Clean this up! */
#if USB_FEATURE #if USB_FEATURE
void USB_feature( void ) void USB_feature(void) {
{
if(game.screenshot && usb_is_open()) { if(game.screenshot && usb_is_open()) {
#if GRAYMODEOK // This is a trick, if GRAYMODEOK is defined then #if GRAYMODEOK // This is a trick, if GRAYMODEOK is defined then
@ -69,7 +70,6 @@ Game game = {
game.screenshot = false; game.screenshot = false;
} }
if(game.record && usb_is_open()) { if(game.record && usb_is_open()) {
#if GRAYMODEOK #if GRAYMODEOK
@ -99,7 +99,7 @@ int main(void) {
gdb_start_on_exception(); gdb_start_on_exception();
#endif /*DEBUGMODE*/ #endif /*DEBUGMODE*/
__printf_enable_fp(); //__printf_enable_fp();
int timer; int timer;
timer = timer_configure(TIMER_TMU, 1000, GINT_CALL(update_time)); timer = timer_configure(TIMER_TMU, 1000, GINT_CALL(update_time));
@ -189,19 +189,17 @@ int main(void) {
/* Management of the inputs */ /* Management of the inputs */
game_get_inputs(&game); game_get_inputs(&game);
/* Run the game at max. 50fps */ /* Run the game at max. 50fps */
while(game.frame_duration < 20) sleep(); while(game.frame_duration < 20)
sleep();
/* Reset frame_duration for the next frame */ /* Reset frame_duration for the next frame */
game.frame_duration = 0; game.frame_duration = 0;
} while(!game.exittoOS); // want to exit ? } while(!game.exittoOS); // want to exit ?
/* shutdown grayengine*/ /* shutdown grayengine*/
#if GRAYMODEOK #if GRAYMODEOK
dgray(DGRAY_OFF); dgray(DGRAY_OFF);
#endif #endif
/* close USB */ /* close USB */
#if USB_FEATURE #if USB_FEATURE
usb_close(); usb_close();
@ -210,4 +208,3 @@ int main(void) {
timer_stop(timer); timer_stop(timer);
return 1; return 1;
} }

View file

@ -1,4 +1,5 @@
#include "map.h" #include "map.h"
#include "config.h" #include "config.h"
#include "game.h" #include "game.h"
@ -8,7 +9,6 @@
extern Map *worldRPG[]; extern Map *worldRPG[];
// extern ExtraData *extraRPG[]; // extern ExtraData *extraRPG[];
void map_render(Game *game) { void map_render(Game *game) {
Map *map_level = game->map_level; Map *map_level = game->map_level;
@ -28,7 +28,8 @@ void map_render(Game *game) {
* y. */ * y. */
unsigned char dw = DWIDTH / T_WIDTH + 2, dh = DHEIGHT / T_HEIGHT + 1; unsigned char dw = DWIDTH / T_WIDTH + 2, dh = DHEIGHT / T_HEIGHT + 1;
/* mw and mh will contain the height and the width of the map. */ /* mw and mh will contain the height and the width of the map. */
unsigned short int mw = map_level->w*T_WIDTH, mh = map_level->h*T_HEIGHT; unsigned short int mw = map_level->w * T_WIDTH,
mh = map_level->h * T_HEIGHT;
/* tile contains the tile to draw. */ /* tile contains the tile to draw. */
short int tile; short int tile;
/* The position where I start drawing */ /* The position where I start drawing */
@ -81,8 +82,8 @@ void map_render(Game *game) {
for(x = 0; x < dw; x++) { for(x = 0; x < dw; x++) {
/* I get the tile number if his position is inside the map. Then /* I get the tile number if his position is inside the map. Then
* I draw it. */ * I draw it. */
if(tx+x>=0 && tx+x < map_level->w && if(tx + x >= 0 && tx + x < map_level->w && ty + y >= 0 &&
ty+y>=0 && ty+y < map_level->h){ ty + y < map_level->h) {
/* index of the current tile */ /* index of the current tile */
current_index = (y + ty) * map_level->w + tx + x; current_index = (y + ty) * map_level->w + tx + x;
/* we get the ID of the tile in the current drawable layers /* we get the ID of the tile in the current drawable layers
@ -124,7 +125,8 @@ void map_render_by_layer(Game *game, int layer) {
* y. */ * y. */
unsigned char dw = DWIDTH / T_WIDTH + 2, dh = DHEIGHT / T_HEIGHT + 1; unsigned char dw = DWIDTH / T_WIDTH + 2, dh = DHEIGHT / T_HEIGHT + 1;
/* mw and mh will contain the height and the width of the map. */ /* mw and mh will contain the height and the width of the map. */
unsigned short int mw = map_level->w*T_WIDTH, mh = map_level->h*T_HEIGHT; unsigned short int mw = map_level->w * T_WIDTH,
mh = map_level->h * T_HEIGHT;
/* tile contains the tile to draw. */ /* tile contains the tile to draw. */
short int tile; short int tile;
/* The position where I start drawing */ /* The position where I start drawing */
@ -172,13 +174,13 @@ void map_render_by_layer(Game *game, int layer) {
for(x = 0; x < dw; x++) { for(x = 0; x < dw; x++) {
/* I get the tile number if his position is inside the map. Then /* I get the tile number if his position is inside the map. Then
* I draw it. */ * I draw it. */
if(tx+x>=0 && tx+x < map_level->w && if(tx + x >= 0 && tx + x < map_level->w && ty + y >= 0 &&
ty+y>=0 && ty+y < map_level->h){ ty + y < map_level->h) {
/* index of the current tile */ /* index of the current tile */
int currentIndex = (y + ty) * map_level->w + tx + x; int currentIndex = (y + ty) * map_level->w + tx + x;
/* we get the ID of the tile in the current drawable layers /* we get the ID of the tile in the current drawable layers
*/ */
tile = map_level->layers[layer][currentIndex]; //DEBUG : Unaligned read here tile = map_level->layers[layer][currentIndex];
/* tile == -1 means nothing to be drawn */ /* tile == -1 means nothing to be drawn */
if(tile >= 0) { if(tile >= 0) {
@ -201,8 +203,9 @@ short int map_get_tile(Game *game, int x, int y, int l) {
/* Get the tile at (x, y) on layer l. Returns the tile ID or MAP_OUTSIDE if /* Get the tile at (x, y) on layer l. Returns the tile ID or MAP_OUTSIDE if
* it's not found. */ * it's not found. */
return (x>=0 && x < (int) map_level->w && y>=0 && y < (int) map_level->h) ? return (x >= 0 && x < (int)map_level->w && y >= 0 && y < (int)map_level->h)
map_level->layers[l][y * map_level->w + x] : MAP_OUTSIDE; ? map_level->layers[l][y * map_level->w + x]
: MAP_OUTSIDE;
} }
short int map_get_walkable(Game *game, int x, int y) { short int map_get_walkable(Game *game, int x, int y) {
@ -210,13 +213,13 @@ short int map_get_walkable(Game *game, int x, int y) {
Map *map_level = game->map_level; Map *map_level = game->map_level;
/* Get the tile at (x, y). Returns the tile ID or MAP_OUTSIDE if she's not /* Get the tile at (x, y). Returns the tile ID or MAP_OUTSIDE if she's not
* found. */ * found. */
return (x>=0 && x < (int) map_level->w && y>=0 && y < (int) map_level->h) ? return (x >= 0 && x < (int)map_level->w && y >= 0 && y < (int)map_level->h)
map_level->walkable[y * map_level->w + x] : MAP_OUTSIDE; ? map_level->walkable[y * map_level->w + x]
: MAP_OUTSIDE;
} }
/* return the pointer to the map containing the given position */ /* return the pointer to the map containing the given position */
Map *map_get_for_coordinates( Game *game, int x, int y ) Map *map_get_for_coordinates(Game *game, int x, int y) {
{
/* check if the current map contains the point */ /* check if the current map contains the point */
if(x >= (int)game->map_level->xmin && x < (int)game->map_level->xmax && if(x >= (int)game->map_level->xmin && x < (int)game->map_level->xmax &&
y >= (int)game->map_level->ymin && y < (int)game->map_level->ymax) { y >= (int)game->map_level->ymin && y < (int)game->map_level->ymax) {

View file

@ -1,24 +1,20 @@
#ifndef MAP_H #ifndef MAP_H
#define MAP_H #define MAP_H
#define BACKGROUND 0 #define BACKGROUND 0
#define FOREGROUND 1 #define FOREGROUND 1
#define MAP_OUTSIDE -2 /* Returned by get_tile_at_pos if the point is outside of #define MAP_OUTSIDE \
-2 /* Returned by get_tile_at_pos if the point is outside of \
* the map. */ * the map. */
#include "game.h" #include "game.h"
#include "player.h" #include "player.h"
/* Structure 'Map' has been moved to game.h */ /* Structure 'Map' has been moved to game.h */
/* to avoid circular references between map.h, game.h and player.h */ /* to avoid circular references between map.h, game.h and player.h */
/* only methods propotypes are now in dedicated header files */ /* only methods propotypes are now in dedicated header files */
/* map_render() /* map_render()
* *
* Draws the map map on the entire screen to be viewed by the player player. * Draws the map map on the entire screen to be viewed by the player player.

View file

@ -1,10 +1,10 @@
#ifndef MAPDATA_H #ifndef MAPDATA_H
#define MAPDATA_H #define MAPDATA_H
#include <stdint.h>
#include "game.h" #include "game.h"
#include <stdint.h>
extern Map *worldRPG[]; extern Map *worldRPG[];
#endif #endif

View file

@ -9,4 +9,3 @@ bool memory_is_in(short int *array, short int array_length, short int item) {
} }
return false; return false;
} }

View file

@ -12,4 +12,3 @@
bool memory_is_in(short int *array, short int array_length, short int item); bool memory_is_in(short int *array, short int array_length, short int item);
#endif #endif

192
src/npc.c
View file

@ -1,29 +1,27 @@
#include "npc.h" #include "npc.h"
#include "config.h"
#include "dialogs.h" #include "dialogs.h"
#include "game.h" #include "game.h"
#include "map.h" #include "map.h"
#include "config.h"
#include <gint/display.h> #include <gint/display.h>
#include <gint/keyboard.h> /*debug*/ #include <gint/keyboard.h> /*debug*/
#include <math.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h>
extern bopti_image_t demo_PNJ_img;
extern bopti_image_t tiny_npc_male;
extern bopti_image_t tiny_npc_female;
extern bopti_image_t tiny_npc_milkman;
extern bopti_image_t tiny_npc_police;
//NPC *npcRPG; //NPC *npcRPG;
//uint32_t nbNPC = 0; //uint32_t nbNPC = 0;
float length( float x, float y ) float length(float x, float y) { return sqrtf(x * x + y * y); }
{
return sqrtf( x*x+y*y );
}
int npc_clear_path(NPC *npc) int npc_clear_path(NPC *npc) {
{
npc->currentPoint = 0; npc->currentPoint = 0;
npc->hasPath = 0; npc->hasPath = 0;
npc->path_length = 0; npc->path_length = 0;
@ -31,47 +29,46 @@ int npc_clear_path(NPC *npc)
free(npc->ypath); free(npc->ypath);
npc->xpath = malloc(4); npc->xpath = malloc(4);
npc->ypath = malloc(4); npc->ypath = malloc(4);
if(npc->xpath == NULL || npc->ypath == NULL) return 1; if(npc->xpath == NULL || npc->ypath == NULL)
return 1;
return 0; return 0;
} }
int npc_append_path(uint16_t x, uint16_t y, NPC *npc) int npc_append_path(uint16_t x, uint16_t y, NPC *npc) {
{
npc->xpath = realloc(npc->xpath, npc->path_length * 2 + 2); npc->xpath = realloc(npc->xpath, npc->path_length * 2 + 2);
npc->ypath = realloc(npc->ypath, npc->path_length * 2 + 2); npc->ypath = realloc(npc->ypath, npc->path_length * 2 + 2);
if(npc->xpath == NULL || npc->ypath == NULL) return 1; if(npc->xpath == NULL || npc->ypath == NULL)
return 1;
npc->path_length++; npc->path_length++;
npc->xpath[npc->path_length - 1] = x - npc->x; npc->xpath[npc->path_length - 1] = x - npc->x;
npc->ypath[npc->path_length - 1] = y - npc->y; npc->ypath[npc->path_length - 1] = y - npc->y;
return 0; return 0;
} }
void as_clean(uint8_t *visited, uint8_t *gscore, uint8_t *fscore) void as_clean(uint8_t *visited, uint8_t *gscore, uint8_t *fscore) {
{
free(visited); free(visited);
free(gscore); free(gscore);
free(fscore); free(fscore);
} }
int as_reconstruct_path(int16_t *came_from, int w, int h, int16_t spos, int as_reconstruct_path(int16_t *came_from, int w, int h, int16_t spos,
int16_t dest, NPC *npc) int16_t dest, NPC *npc) {
{ if(npc_clear_path(npc))
if(npc_clear_path(npc)) goto as_recons_fail; goto as_recons_fail;
int16_t next = came_from[dest]; int16_t next = came_from[dest];
unsigned int i; unsigned int i;
for(i = 0; i < 64; i++) for(i = 0; i < 64; i++) {
{ if(npc_append_path((next % w) * T_WIDTH, (next / h) * T_HEIGHT, npc)) {
if(npc_append_path((next%w)*T_WIDTH,(next/h)*T_HEIGHT, npc))
{
goto as_recons_fail; goto as_recons_fail;
} }
next = came_from[next]; next = came_from[next];
if(next == spos) { if(next == spos) {
if(npc_append_path((spos%w)*T_WIDTH,(spos/h)*T_HEIGHT, npc)) if(npc_append_path((spos % w) * T_WIDTH, (spos / h) * T_HEIGHT,
npc))
goto as_recons_fail; goto as_recons_fail;
break; break;
} }
@ -81,8 +78,7 @@ int as_reconstruct_path(int16_t *came_from, int w, int h, int16_t spos,
// Flip the path because it started from the end // Flip the path because it started from the end
for(i = 0; i < npc->path_length/2; i++) for(i = 0; i < npc->path_length / 2; i++) {
{
tx = npc->xpath[i]; tx = npc->xpath[i];
ty = npc->ypath[i]; ty = npc->ypath[i];
npc->xpath[i] = npc->xpath[npc->path_length - i - 1]; npc->xpath[i] = npc->xpath[npc->path_length - i - 1];
@ -107,8 +103,7 @@ int as_reconstruct_path(int16_t *came_from, int w, int h, int16_t spos,
// Returns non zero error code on failure // Returns non zero error code on failure
// Custom a* implemetation // Custom a* implemetation
// Unoptimized, may become an issue // Unoptimized, may become an issue
int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc) int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc) {
{
int32_t i, j; int32_t i, j;
int32_t w = full_map->w; int32_t w = full_map->w;
@ -121,46 +116,53 @@ int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc)
uint8_t *map = full_map->walkable; uint8_t *map = full_map->walkable;
if(dest_x < 0 || dest_x > w || dest_y < 0 || dest_x > h) return 2; if(dest_x < 0 || dest_x > w || dest_y < 0 || dest_x > h)
if(map[spos]) return 2; return 2;
if(map[dest_y*w+dest_x]) return 2; if(map[spos])
return 2;
if(map[dest_y * w + dest_x])
return 2;
npc_clear_path(npc); npc_clear_path(npc);
uint8_t *visited = malloc(w * h); uint8_t *visited = malloc(w * h);
for(i=0; i<w*h; i++) visited[i] = 1; for(i = 0; i < w * h; i++)
visited[i] = 1;
visited[spos] = 0; visited[spos] = 0;
int16_t *came_from = malloc(w * h * 2); int16_t *came_from = malloc(w * h * 2);
for(i=0; i<w*h; i++) came_from[i] = -1; for(i = 0; i < w * h; i++)
came_from[i] = -1;
uint8_t *gscore = malloc(w * h * 2); uint8_t *gscore = malloc(w * h * 2);
for(i=0; i<w*h; i++) gscore[i] = 255; for(i = 0; i < w * h; i++)
gscore[i] = 255;
gscore[spos] = 0; gscore[spos] = 0;
uint8_t *fscore = malloc(w * h * 2); uint8_t *fscore = malloc(w * h * 2);
for(i=0; i<w*h; i++) fscore[i] = 255; for(i = 0; i < w * h; i++)
fscore[i] = 255;
fscore[spos] = length(dest_x - x, dest_y - y); fscore[spos] = length(dest_x - x, dest_y - y);
uint8_t bscore; uint8_t bscore;
int32_t bx = x; int32_t bx = x;
int32_t by = y; int32_t by = y;
for(int iter=0; iter < 64; iter++) for(int iter = 0; iter < 64; iter++) {
{
bscore = 255; bscore = 255;
// Cheapest known tile // Cheapest known tile
for(i = 0; i <= w*h; i++) for(i = 0; i <= w * h; i++) {
{ if(visited[i])
if(visited[i]) continue; continue;
if(map[i] == 1) continue; if(map[i] == 1)
if(fscore[i] > bscore) continue; continue;
if(fscore[i] > bscore)
continue;
bx = i % w; bx = i % w;
by = i / w; by = i / w;
bscore = fscore[i]; bscore = fscore[i];
} }
if(bx == dest_x && by == dest_y) if(bx == dest_x && by == dest_y) {
{
as_clean(visited, gscore, fscore); as_clean(visited, gscore, fscore);
return as_reconstruct_path(came_from, w, h, spos, return as_reconstruct_path(came_from, w, h, spos,
dest_y * w + dest_x, npc); dest_y * w + dest_x, npc);
@ -170,22 +172,24 @@ int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc)
int att_score; int att_score;
for(i = bx-1; i < bx+2; i++) for(i = bx - 1; i < bx + 2; i++) {
{ if(i > w)
if(i > w) break; break;
for(j = by-1; j < by+2; j++) for(j = by - 1; j < by + 2; j++) {
{ if(j > h)
if(j > h) break; break;
if(map[j*w+i] == 1) continue; if(map[j * w + i] == 1)
if(i == bx && j == by) continue; continue;
if(i == bx && j == by)
continue;
att_score = gscore[by * w + bx] + round(length(bx - i, by - j)); att_score = gscore[by * w + bx] + round(length(bx - i, by - j));
if(att_score < gscore[j*w+i]) if(att_score < gscore[j * w + i]) {
{
came_from[j * w + i] = by * w + bx; came_from[j * w + i] = by * w + bx;
gscore[j * w + i] = att_score; gscore[j * w + i] = att_score;
fscore[j*w+i] = att_score + round( fscore[j * w + i] =
length(dest_x-i, dest_y-j)); att_score + round(length(dest_x - i, dest_y - j));
if(visited[j*w+i]) visited[j*w+i] = 0; if(visited[j * w + i])
visited[j * w + i] = 0;
} }
} }
} }
@ -197,27 +201,24 @@ int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc)
return 3; return 3;
} }
/*The following functions need to be redone*/ /*NPC *npc_create() {
/*
NPC *npc_create()
{
// Use temp pointer to avoid breaking the whole npcRPG on failure // Use temp pointer to avoid breaking the whole npcRPG on failure
void *temp = realloc(npcRPG, (nbNPC + 1) * sizeof(NPC)); void *temp = realloc(npcRPG, (nbNPC + 1) * sizeof(NPC));
if(temp == NULL) return NULL; if(temp == NULL)
return NULL;
npcRPG = temp; npcRPG = temp;
nbNPC++; nbNPC++;
NPC *npc = &npcRPG[nbNPC - 1]; NPC *npc = &npcRPG[nbNPC - 1];
npc->xpath = malloc(2); npc->xpath = malloc(2);
npc->ypath = malloc(2); npc->ypath = malloc(2);
return npc; return npc;
} }*/
void npc_remove(NPC *npc) /*void npc_remove(NPC *npc) {
{
uint32_t pos = ((uint32_t)npc - (uint32_t)npcRPG) / sizeof(NPC); uint32_t pos = ((uint32_t)npc - (uint32_t)npcRPG) / sizeof(NPC);
if(pos > nbNPC-1) return; if(pos > nbNPC - 1)
if(pos == nbNPC-1) return;
{ if(pos == nbNPC - 1) {
nbNPC--; nbNPC--;
return; return;
} }
@ -233,64 +234,53 @@ void update_npcs([[maybe_unused]] Game *game)
} }
} }
void update_npc(NPC *npc) void update_npc(NPC *npc) {
{
/* if the NPC has no path or is paused, skip it */ /* if the NPC has no path or is paused, skip it */
if (!npc->hasPath || npc->paused==true) return; if(!npc->hasPath || npc->paused == true)
return;
float vecX = (float) (npc->xpath[ npc->currentPoint ] + float vecX = (float)(npc->xpath[npc->currentPoint] + npc->x) - npc->curx;
npc->x) - npc->curx; float vecY = (float)(npc->ypath[npc->currentPoint] + npc->y) - npc->cury;
float vecY = (float) (npc->ypath[ npc->currentPoint ] +
npc->y) - npc->cury;
float vecN = length(vecX, vecY); float vecN = length(vecX, vecY);
if (vecN>0.5f) if(vecN > 0.5f) {
{
vecX /= vecN * 2.0; vecX /= vecN * 2.0;
vecY /= vecN * 2.0; vecY /= vecN * 2.0;
} } else {
else
{
npc->currentPoint++; npc->currentPoint++;
npc->currentPoint = npc->currentPoint % npc->path_length; npc->currentPoint = npc->currentPoint % npc->path_length;
} }
npc->curx += vecX; npc->curx += vecX;
npc->cury += vecY; npc->cury += vecY;
} }
/*void reload_npc(Game *game) /*void reload_npc(Game *game) {
{ if(npcRPG != NULL) {
if (npcRPG!=NULL)
{
free(npcRPG); free(npcRPG);
npcRPG = NULL; npcRPG = NULL;
} }
nbNPC = 0; nbNPC = 0;
for(uint32_t u = 0; u < game->map_level->nbextradata; u++) {
for (uint32_t u=0; u<game->map_level->nbextradata; u++)
{
ExtraData *Data = &game->map_level->extradata[u]; ExtraData *Data = &game->map_level->extradata[u];
if (strcmp(Data->type, "NPC")==0) //the current data is a NPC if(strcmp(Data->type, "NPC") == 0)
{ {
nbNPC++; nbNPC++;
} }
} }
npcRPG = (NPC *)malloc(nbNPC * sizeof(NPC)); npcRPG = (NPC *)malloc(nbNPC * sizeof(NPC));
if(npcRPG == NULL) return; if(npcRPG == NULL)
return;
int currentNPC = 0; int currentNPC = 0;
for (uint32_t u=0; u<game->map_level->nbextradata; u++) for(uint32_t u = 0; u < game->map_level->nbextradata; u++) {
{
ExtraData *Data = &game->map_level->extradata[u]; ExtraData *Data = &game->map_level->extradata[u];
if (strcmp(Data->type, "NPC")==0) //the current data is a NPC if(strcmp(Data->type, "NPC") == 0)
{ {
npcRPG[currentNPC].curx = (float)Data->x; npcRPG[currentNPC].curx = (float)Data->x;
npcRPG[currentNPC].cury = (float)Data->y; npcRPG[currentNPC].cury = (float)Data->y;
@ -311,6 +301,13 @@ void update_npc(NPC *npc)
void npc_draw(Game *game) { void npc_draw(Game *game) {
Player *pl = &game->player; Player *pl = &game->player;
size_t i;
const bopti_image_t *npc_sprites[FACES] = {
&tiny_npc_male,
&tiny_npc_female,
&tiny_npc_milkman,
&tiny_npc_police
};
for (uint32_t u=0; u<game->map_level->nbNPC; u++) for (uint32_t u=0; u<game->map_level->nbNPC; u++)
{ {
@ -343,6 +340,7 @@ void npc_draw(Game *game) {
int16_t delX = ((int16_t)(Data->curx * PXSIZE)) - (int16_t)pl->wx; int16_t delX = ((int16_t)(Data->curx * PXSIZE)) - (int16_t)pl->wx;
int16_t delY = ((int16_t)(Data->cury * PXSIZE)) - (int16_t)pl->wy; int16_t delY = ((int16_t)(Data->cury * PXSIZE)) - (int16_t)pl->wy;
dimage( pl->px-P_WIDTH/2+delX, pl->py-P_HEIGHT/2+delY, &demo_PNJ_img); bopti_image_t *face = npc_sprites[Data->face];
dimage(pl->px - P_WIDTH / 2 + delX, pl->py - P_HEIGHT / 2 + delY, face);
} }
} }

View file

@ -1,15 +1,13 @@
#ifndef NPC_H #ifndef NPC_H
#define NPC_H #define NPC_H
#include <stdbool.h>
#include <stdint.h>
#include "game.h" #include "game.h"
#include "memory.h" #include "memory.h"
enum #include <stdbool.h>
{ #include <stdint.h>
enum {
NPC_NONE = 0, NPC_NONE = 0,
NPC_FRIENDLY = 1, // The player's team NPC_FRIENDLY = 1, // The player's team
@ -31,13 +29,12 @@ int npc_append_path(uint16_t x, uint16_t y, NPC *npc);
// Returns non-zero on failure // Returns non-zero on failure
int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc); int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc);
/*
// realloc()s npcRPG to adequate size and returns a pointer to the new element // realloc()s npcRPG to adequate size and returns a pointer to the new element
// Returns NULL on failure // Returns NULL on failure
NPC *npc_create(); NPC *npc_create();
// Pops the NPC from npcRPG // Pops the NPC from npcRPG
void npc_remove(NPC *npc);*/ void npc_remove(NPC *npc);
/* Draws the player player. This function should be called after drawing the /* Draws the player player. This function should be called after drawing the
* map! */ * map! */
@ -50,4 +47,3 @@ void update_npc(NPC *npc);
void reload_npc(Game *game); void reload_npc(Game *game);
#endif #endif

View file

@ -1,19 +1,15 @@
#include "player.h" #include "player.h"
#include "config.h"
#include "dialogs.h" #include "dialogs.h"
#include "game.h" #include "game.h"
#include "map.h" #include "map.h"
#include "config.h"
#include "npc.h" #include "npc.h"
#include <gint/display.h> #include <gint/display.h>
#define FACES 4 extern bopti_image_t player_male_img;
extern bopti_image_t player_female_img;
struct Face {
const char *name;
bopti_image_t *face;
};
extern bopti_image_t demo_player_img;
extern bopti_image_t npc_male; extern bopti_image_t npc_male;
extern bopti_image_t npc_female; extern bopti_image_t npc_female;
extern bopti_image_t npc_milkman; extern bopti_image_t npc_milkman;
@ -21,11 +17,11 @@ extern bopti_image_t npc_police;
extern bopti_image_t SGN_Icon_img; extern bopti_image_t SGN_Icon_img;
extern bopti_image_t INFO_Icon_img; extern bopti_image_t INFO_Icon_img;
const struct Face faces[FACES] = { const bopti_image_t *faces[FACES] = {
{"MALE", &npc_male}, &npc_male,
{"FEMALE", &npc_female}, &npc_female,
{"MILKMAN", &npc_milkman}, &npc_milkman,
{"POLICE", &npc_police} &npc_police
}; };
const char one_px_mov[8] = { const char one_px_mov[8] = {
@ -39,31 +35,26 @@ const char one_px_mov[8] = {
* IDs */ * IDs */
/* The speed of the player on the diffrent tiles in the walkable layer. */ /* The speed of the player on the diffrent tiles in the walkable layer. */
#define WALKABLE_TILE_MAX 4 #define WALKABLE_TILE_MAX 4
const short int walkable_speed[WALKABLE_TILE_MAX] = { const short int walkable_speed[WALKABLE_TILE_MAX] = {SPEED, 0, PXSIZE, PXSIZE};
SPEED, 0, PXSIZE, PXSIZE
};
/* How much damage the player takes on the diffrent tiles in the walkable /* How much damage the player takes on the diffrent tiles in the walkable
* layer. */ * layer. */
const char damage_taken_walkable[WALKABLE_TILE_MAX] = { const char damage_taken_walkable[WALKABLE_TILE_MAX] = {0, 0, 5, 0};
0, 0, 5, 0
};
extern bopti_image_t demo_player_img; extern bopti_image_t demo_player_img;
//extern NPC *npcRPG; extern NPC *npcRPG;
//extern uint32_t nbNPC; extern uint32_t nbNPC;
void player_draw(Game *game) { void player_draw(Game *game) {
Player *player = &game->player; Player *player = &game->player;
dimage(player->px-P_WIDTH/2, player->py-P_HEIGHT/2, &demo_player_img); dimage(player->px - P_WIDTH / 2, player->py - P_HEIGHT / 2,
player->is_male ? &player_male_img : &player_female_img);
} }
void player_move(Game *game, Direction direction) { void player_move(Game *game, Direction direction) {
Player *player = &game->player; Player *player = &game->player;
/* How this player movement will modify the player x and y. */ /* How this player movement will modify the player x and y. */
char dx, dy; char dx, dy;
@ -77,8 +68,7 @@ void player_move(Game *game, Direction direction) {
dy = one_px_mov[direction * 2 + 1] * player->speed; dy = one_px_mov[direction * 2 + 1] * player->speed;
player_fix_position(game, dx, dy); player_fix_position(game, dx, dy);
} } else {
else{
if(player_collision(game, direction, P_RIGHTDOWN) || if(player_collision(game, direction, P_RIGHTDOWN) ||
player_collision(game, direction, P_LEFTUP)) { player_collision(game, direction, P_LEFTUP)) {
@ -106,6 +96,7 @@ void player_move(Game *game, Direction direction) {
} }
void player_action(Game *game) { void player_action(Game *game) {
size_t i;
/* already doing something, or can't do anything*/ /* already doing something, or can't do anything*/
if(game->player.isDoingAction || !game->player.canDoSomething) return; if(game->player.isDoingAction || !game->player.canDoSomething) return;
@ -142,9 +133,10 @@ void player_action(Game *game) {
NPC *currentNPC = &game->map_level->npcs[game->player.whichAction]; NPC *currentNPC = &game->map_level->npcs[game->player.whichAction];
/* we use the correct image as per the class of the item */ /* we use the correct image as per the class of the item */
/*TODO*/
bopti_image_t *face = &npc_male; bopti_image_t *face = &npc_male;
/* It's a NPC */
face = faces[currentNPC->face];
uint32_t dialogStart = currentNPC->dialogID; uint32_t dialogStart = currentNPC->dialogID;
/* we set this NPC to paused to avoid changing its position while /* we set this NPC to paused to avoid changing its position while
@ -158,9 +150,6 @@ void player_action(Game *game) {
currentNPC->paused = false; currentNPC->paused = false;
} }
} }
bool player_collision(Game *game, Direction direction, bool player_collision(Game *game, Direction direction,
@ -235,18 +224,22 @@ bool player_collision(Game *game, Direction direction,
} }
} }
/* Handle a negative position differently than a positive one. */ /* Handle a negative position differently than a positive one. */
if(player_tile_x < 0) player_tile_x = player_tile_x/T_WIDTH-1; if(player_tile_x < 0)
else player_tile_x = player_tile_x/T_WIDTH; player_tile_x = player_tile_x / T_WIDTH - 1;
else
player_tile_x = player_tile_x / T_WIDTH;
if(player_tile_y < 0) player_tile_y = player_tile_y/T_HEIGHT-1; if(player_tile_y < 0)
else player_tile_y = player_tile_y/T_HEIGHT; player_tile_y = player_tile_y / T_HEIGHT - 1;
else
player_tile_y = player_tile_y / T_HEIGHT;
int on_walkable = map_get_walkable(game, player_tile_x, player_tile_y); int on_walkable = map_get_walkable(game, player_tile_x, player_tile_y);
int speed = (on_walkable >= 0 && on_walkable < WALKABLE_TILE_MAX) ? int speed = (on_walkable >= 0 && on_walkable < WALKABLE_TILE_MAX)
walkable_speed[on_walkable] : 0; ? walkable_speed[on_walkable]
: 0;
/* if he's on a hard tile */ /* if he's on a hard tile */
if(!speed) { if(!speed) {
@ -264,9 +257,11 @@ void player_fix_position(Game *game, bool fix_x, bool fix_y) {
/* I fix his poition on x or/and on y if y need to, so that he won't be over /* I fix his poition on x or/and on y if y need to, so that he won't be over
* the hard tile that he collided with. */ * the hard tile that he collided with. */
if(fix_x) player->x = player->x/T_WIDTH*T_WIDTH+P_WIDTH/2; if(fix_x)
player->x = player->x / T_WIDTH * T_WIDTH + P_WIDTH / 2;
if(fix_y) player->y = player->y/T_HEIGHT*T_HEIGHT+P_HEIGHT/2; if(fix_y)
player->y = player->y / T_HEIGHT * T_HEIGHT + P_HEIGHT / 2;
} }
void player_damage(Game *game, int amount) { void player_damage(Game *game, int amount) {
@ -276,4 +271,3 @@ void player_damage(Game *game, int amount) {
player->life -= amount; player->life -= amount;
/* TODO: Let the player dye if life < 1. */ /* TODO: Let the player dye if life < 1. */
}; };

View file

@ -1,16 +1,23 @@
#ifndef PLAYER_H #ifndef PLAYER_H
#define PLAYER_H #define PLAYER_H
#include <stdbool.h>
#include "config.h" #include "config.h"
#include "game.h" #include "game.h"
#include "memory.h" #include "memory.h"
#include <stdbool.h>
typedef struct {
const char *name;
bopti_image_t *face;
} Face;
#define FACES 4
/* Structure 'Player' has been moved to game.h */ /* Structure 'Player' has been moved to game.h */
/* to avoid circular references between map.h, game.h and player.h */ /* to avoid circular references between map.h, game.h and player.h */
/* only methods propotypes are now in dedicated header files */ /* only methods propotypes are now in dedicated header files */
/* player_draw() /* player_draw()
* *
* Draws the player. This function should be called after drawing the * Draws the player. This function should be called after drawing the
@ -51,7 +58,6 @@ bool player_collision(Game *game, Direction direction,
*/ */
void player_fix_position(Game *game, bool fix_x, bool fix_y); void player_fix_position(Game *game, bool fix_x, bool fix_y);
/* player_damage() /* player_damage()
* *
* Apply damage to player * Apply damage to player
@ -61,4 +67,3 @@ void player_fix_position(Game *game, bool fix_x, bool fix_y);
void player_damage(Game *game, int amount); void player_damage(Game *game, int amount);
#endif #endif