Revert "Merge branch 'dev' of git.planet-casio.com:Slyvtt/Collab_RPG"

This reverts commit 685e4b8824, reversing
changes made to 9929e7bb08.
This commit is contained in:
mibi88 2024-07-27 15:26:55 +02:00
parent 5c58e11fea
commit 74d30dc575
49 changed files with 288 additions and 626 deletions

1
.gitignore vendored
View file

@ -2,7 +2,6 @@
/build-fx
/build-cg
/build-cg-push
/build-fxg3a
/*.g1a
/*.g3a

View file

@ -8,8 +8,7 @@ include(GenerateG1A)
include(GenerateG3A)
include(Fxconv)
find_package(Gint 2.11 REQUIRED)
# Gint 2.11 is required, because we're using the new macros like GINT_RENDER_RGB
find_package(Gint 2.9 REQUIRED)
find_package(LibProf 2.4 REQUIRED)
#set the color mode either to 1b or 2b
@ -37,12 +36,9 @@ set(ASSETS
set(ASSETS_cg
assets-cg/demo_player.png
assets-cg/npc/char/npc_male.png
assets-cg/demo_PNJ.png
assets-cg/SignAction.png
assets-cg/npc/face/npc_male.png
assets-cg/npc/face/npc_female.png
assets-cg/npc/face/npc_milkman.png
assets-cg/npc/face/npc_police.png
assets-cg/NPC_Icon.png
assets-cg/SGN_Icon.png
assets-cg/INFO_Icon.png
assets-cg/player_face.png
@ -63,12 +59,9 @@ set(ASSETS_cg_EGA64
set(ASSETS_fx
assets-fx/demo_player.png
assets-fx/npc/char/npc_male.png
assets-fx/demo_PNJ.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/NPC_Icon.png
assets-fx/SGN_Icon.png
assets-fx/INFO_Icon.png
assets-fx/player_face.png
@ -92,8 +85,29 @@ if("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G)
add_executable(myaddin ${SOURCES} ${ASSETS} ${ASSETS_${FXSDK_PLATFORM}} ${ASSETS_${FXSDK_PLATFORM}_${COLORMODE_fx}} )
elseif("${FXSDK_PLATFORM_LONG}" STREQUAL fxCG50)
add_executable(myaddin ${SOURCES} ${ASSETS} ${ASSETS_${FXSDK_PLATFORM}} ${ASSETS_${FXSDK_PLATFORM}_${COLORMODE_cg}} )
elseif("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G_G3A)
add_executable(myaddin ${SOURCES} ${ASSETS} ${ASSETS_${FXSDK_PLATFORM}} ${ASSETS_${FXSDK_PLATFORM}_${COLORMODE_fx}} )
endif()
# fx colormode
if("${COLORMODE_fx}" STREQUAL 1b)
target_compile_options(myaddin PRIVATE -Wall -Wextra -Os -DCOLOR1BIT)
endif()
if("${COLORMODE_fx}" STREQUAL 2b)
target_compile_options(myaddin PRIVATE -Wall -Wextra -Os -DCOLOR2BIT)
endif()
# cg colormode
if("${COLORMODE_cg}" STREQUAL 1b)
target_compile_options(myaddin PRIVATE -Wall -Wextra -Os -DCOLOR1BIT)
endif()
if("${COLORMODE_cg}" STREQUAL 2b)
target_compile_options(myaddin PRIVATE -Wall -Wextra -Os -DCOLOR2BIT)
endif()
if("${COLORMODE_cg}" STREQUAL EGA64)
target_compile_options(myaddin PRIVATE -Wall -Wextra -Os -DCOLOREGA)
endif()
target_link_options(myaddin PRIVATE -Wl,-Map=Build_Addin.map -Wl,--print-memory-usage)
@ -101,14 +115,6 @@ target_link_libraries(myaddin LibProf::LibProf Gint::Gint)
if("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G)
# fx colormode
if("${COLORMODE_fx}" STREQUAL 1b)
target_compile_options(myaddin PRIVATE -Wall -Wextra -Os -DCOLOR1BIT)
endif()
if("${COLORMODE_fx}" STREQUAL 2b)
target_compile_options(myaddin PRIVATE -Wall -Wextra -Os -DCOLOR2BIT)
endif()
if("${COLORMODE_fx}" STREQUAL 1b)
generate_g1a(TARGET myaddin OUTPUT "RPG_1b.g1a"
@ -121,20 +127,7 @@ if("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G)
endif()
elseif("${FXSDK_PLATFORM_LONG}" STREQUAL fxCG50)
# cg colormode
if("${COLORMODE_cg}" STREQUAL 1b)
target_compile_options(myaddin PRIVATE -Wall -Wextra -Os -DCOLOR1BIT)
endif()
if("${COLORMODE_cg}" STREQUAL 2b)
target_compile_options(myaddin PRIVATE -Wall -Wextra -Os -DCOLOR2BIT)
endif()
if("${COLORMODE_cg}" STREQUAL EGA64)
target_compile_options(myaddin PRIVATE -Wall -Wextra -Os -DCOLOREGA)
endif()
if("${COLORMODE_cg}" STREQUAL 1b)
generate_g3a(TARGET myaddin OUTPUT "RPG_1b.g3a"
@ -151,19 +144,4 @@ elseif("${FXSDK_PLATFORM_LONG}" STREQUAL fxCG50)
NAME "RPG PC EGA" ICONS assets-cg/ega64/icon-uns-ega64.png assets-cg/ega64/icon-sel-ega64.png)
endif()
elseif("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G_G3A)
if("${COLORMODE_fx}" STREQUAL 1b)
generate_g3a(TARGET myaddin OUTPUT "RPG_1bfx.g3a"
NAME "RPG PC 1b fx" ICONS assets-cg/1b/icon-uns-1b.png assets-cg/1b/icon-sel-1b.png)
endif()
if("${COLORMODE_fx}" STREQUAL 2b)
generate_g3a(TARGET myaddin OUTPUT "RPG_2bfx.g3a"
NAME "RPG PC 2b fx" ICONS assets-cg/2b/icon-uns-2b.png assets-cg/2b/icon-sel-2b.png)
endif()
endif()

View file

@ -1,26 +0,0 @@
# Project structure
* `assets` contains the tiled maps, and the tiled map converters.
* `assets-cg` contains the assets for cg calculators like the cg-50.
* `assets-fx` contains the assets for monochrome calculators.
* `captures` contains screenshots.
* `src` This folder contains the source code.
* `config.h` This header file contains defines for the size of various
things on screen, like the size of a tile in the tilemap, the size of the
dialog box, etc.
* `dialogs.c` and `dialogs.h` contain various functions to display dialogs
and also let the user respond.
* `events.c` and `events.h` parse tags in the messages that are displayed
using the dialogs procedures to modify variables (and soon, call
procedures).
* `game.c` and `game.h` handles the rendering, the input, etc.
* `main.c` handles the USB connection and the gint gray rendering, for 2bpp
rendering on monochrome calculators. Contains the mainloop. Also contains
code to display debug informations.
* `map.c` and `map.h` contain code to render, get a tile in the map, see if
the tile is walkable, etc.
* `mapdata.h` contains the available maps.
* `memory.c` and `memory.h` procedures to handle arrays (currently: search
in an array of short ints).
* `npc.c` and `npc.h` npc rendering and movement (and soon pathfinding).
* `player.c` and `player.h` handle the player movement, collision, etc.

View file

@ -2,12 +2,7 @@
Plus d'infos sur ce projet ici : [Le projet Collaboratif de PC](https://www.planet-casio.com/Fr/forums/topic17343-last-projet-collaboratif-avec-toute-la-commu.html)
## Contribuer!
Style du code [STYLE.md](STYLE.md).
Structure du projet [PROJECT_STRUCTURE.md](PROJECT_STRUCTURE.md).
## Avancement du projet
## Avencement du projet
A ce stade, on a déjà implémenté :
@ -18,13 +13,12 @@ A ce stade, on a déjà implémenté :
- [x] Multiple cartes avec importation automatique des fichiers `world` issus de Tiled
- [x] Carte Multilayer (Background, Foreground + accessibilité / Dommages) avec transparence du calque Foreground
- [x] Personnage
- [x] Dialogues avec fichiers externes `json` et séquenceage possible de ceux-ci via un arbre d'histoire (sauts de lignes et mots plus grands que l'écran pas supportés + limite d'un kibibyte)
- [x] Dialogues avec fichiers externes `json` et séquenceage possible de ceux-ci via un arbre d'histoire (sauts de lignes et mots plus grands que l'écran pas supportés)
- [x] Fontes de caractères
- [x] Interaction
- [ ] NPC
- [x] Changement de map durant le jeu
- [ ] Système d'événements
- [ ] Pathfinding
## Crédits

View file

@ -1,44 +0,0 @@
# Planet Casio Collaborative Project
(maybe I should've used google translate)
More informations can be found here (in french):
[Le projet Collaboratif de PC](https://www.planet-casio.com/Fr/forums/topic17343-last-projet-collaboratif-avec-toute-la-commu.html)
## Contribute!
Style guidelines [STYLE.md](STYLE.md).
Project structure [PROJECT_STRUCTURE.md](PROJECT_STRUCTURE.md).
## Current state
What we've implemented so far:
- [x] Screenshots via USB
- [x] Displaying the current map at the players position
- [x] Handling keyboard inputs
- [x] Handling collisions.
- [x] Multiple maps with automatic `world` files import (made with Tiled)
- [x] Multilayer map (Background, Foreground + accessibility / damage) with
foreground layer transparency.
- [x] Player character.
- [x] Dialogs from external `json` files (line jumps and words bigger than the
screen are unsupported + 1 kibibyte per message limit)
- [x] Font
- [x] Interaction
- [ ] NPC
- [x] Changing map in game.
- [ ] Event system
- [ ] Pathfinding
## Credits
The tiles are from Game Boy Top-down RPG Fantasy Tileset (FREE)
"Background Assets by Gumpy Function (gumpyfunction.itch.io)"
[Tiles Background Assets by Gumpy Function](https://gumpyfunction.itch.io/game-boy-rpg-fantasy-tileset-free)
Converted to greyscale with gimp.
1-bit (black and white) version by Shadow15510
CG (palette EGA64) color version by Fcalva

View file

@ -1,33 +0,0 @@
# Style guidelines in Collab RPG
(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.
(Mibi88) SlyVTT, Fcalva, should be use a doc generation thing or do we describe
the procedures as I did so far?
Document your procedures as following:
```C
/* procedure_name()
*
* 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?

BIN
assets-cg/NPC_Icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

BIN
assets-cg/demo_PNJ.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 B

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 41 KiB

View file

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 167 B

View file

@ -1,12 +0,0 @@
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.

Before

Width:  |  Height:  |  Size: 510 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 494 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 544 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 B

BIN
assets-fx/NPC_Icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

BIN
assets-fx/demo_PNJ.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 B

After

Width:  |  Height:  |  Size: 105 B

View file

@ -2,6 +2,10 @@ demo_player.png:
type: bopti-image
name: demo_player_img
demo_PNJ.png:
type: bopti-image
name: demo_PNJ_img
player_face.png:
type: bopti-image
name: player_face_img
@ -14,6 +18,10 @@ INFO_Icon.png:
type: bopti-image
name: INFO_Icon_img
NPC_Icon.png:
type: bopti-image
name: NPC_Icon_img
SGN_Icon.png:
type: bopti-image
name: SGN_Icon_img
@ -26,4 +34,4 @@ font.png:
grid.padding: 1
grid.border: 0
proportional: true
height: 5
height: 5

View file

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 B

View file

@ -1,12 +0,0 @@
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.

Before

Width:  |  Height:  |  Size: 327 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 354 B

View file

@ -6,7 +6,6 @@ import pathlib
import csv
import os
DEBUG = 0
def convert(input, output, params, target):
if params["custom-type"] == "map":
@ -35,8 +34,8 @@ def convert_world(input, output, params, target):
data = json.load(open(input, "r"))
nbMaps = ["fileName" in i for i in data["maps"]].count(True)
if DEBUG: print( "We have to treat ", nbMaps, " maps")
if DEBUG: print( "So let's go ... ")
print( "We have to treat ", nbMaps, " maps")
print( "So let's go ... ")
structWorld = fxconv.Structure()
#structExtra = fxconv.Structure()
@ -52,26 +51,26 @@ def convert_world(input, output, params, target):
nameJSON = "/".join(input.split("/")[:-nbRetour]) + "/" + nameMap + ".json"
commandline = 'tiled --export-map json ' + nameTMX + ' ' + nameJSON
if DEBUG: print( "TILED COMMAND LINE FOR MAPS : ", commandline )
print( "TILED COMMAND LINE FOR MAPS : ", commandline )
os.system( commandline )
mapPath = "/".join(input.split("/")[:-nbRetour]) + "/" + nameMap + ".json"
if DEBUG: print("Map ", i , " name : ", mapPath )
print("Map ", i , " name : ", mapPath )
xmin = data["maps"][i]["x"]
if DEBUG: print( "xmin = ", xmin )
print( "xmin = ", xmin )
ymin = data["maps"][i]["y"]
if DEBUG: print( "ymin = ", ymin )
print( "ymin = ", ymin )
xmax = data["maps"][i]["x"] + data["maps"][i]["width"]
if DEBUG: print( "xmax = ", xmax )
print( "xmax = ", xmax )
ymax = data["maps"][i]["y"] + data["maps"][i]["height"]
if DEBUG: print( "ymax = ", ymax )
print( "ymax = ", ymax )
map = get_tile_map_data( mapPath, output, params, target, xmin, ymin, xmax, ymax)
if DEBUG: print( "Map = ", map )
print( "Map = ", map )
structWorld += fxconv.ptr( map )
structWorld += fxconv.u32(0)
@ -86,7 +85,7 @@ def get_tile_map_data(input, output, params, target, xmin, ymin, xmax, ymax):
#find the tileset in use. it's a relative path (like ../tileset.tsx)
nameTileset = data["tilesets"][0]["source"].replace(".tsx","")
if DEBUG: print(nameTileset)
print(nameTileset)
#the name of the tileset without the .something
nameTilesetFree = nameTileset.split("/")[-1]
#count the number of "back" (cd ..) to locate the tileset on the computer
@ -96,7 +95,7 @@ def get_tile_map_data(input, output, params, target, xmin, ymin, xmax, ymax):
tilesetJSON = "/".join(input.split("/")[:-nbRetour]) + "/" + nameTileset + ".json"
commandline = 'tiled --export-tileset json ' + tilesetTSX + ' ' + tilesetJSON
if DEBUG: print( "TILED COMMAND LINE FOR TILESET : ", commandline )
print( "TILED COMMAND LINE FOR TILESET : ", commandline )
os.system( commandline )
tileset = open(tilesetJSON, "r")
@ -106,14 +105,14 @@ def get_tile_map_data(input, output, params, target, xmin, ymin, xmax, ymax):
#find the ID of the first tile in the walkable tileset ()
indexWalkable = data["tilesets"][1]["firstgid"]
if DEBUG: print(indexWalkable)
print(indexWalkable)
#Extract from the json the width, height
w, h = data["width"], data["height"]
#nbTileLayer is the number of "true" layers (without ObjectsLayer)
nbTilelayer = ["data" in i for i in data["layers"]].count(True) - 1
if DEBUG: print( nbTilelayer)
print( nbTilelayer)
#index of the various layers (may change from one map to another)
layer_walkable = 0
@ -136,7 +135,7 @@ def get_tile_map_data(input, output, params, target, xmin, ymin, xmax, ymax):
datavalid = data["layers"][i]
if datavalid["name"]=="Walkable":
layer_walkable = i
if DEBUG: print( "Walkable Tile Data in layer : ", layer_walkable)
print( "Walkable Tile Data in layer : ", layer_walkable)
break
elif i==nbTilelayer:
print( "ERROR : No Walkable layer data !!!" )
@ -169,7 +168,7 @@ def get_tile_map_data(input, output, params, target, xmin, ymin, xmax, ymax):
nameDialog = data["properties"][0]["value"]
dialogfile = "/".join(input.split("/")[:-nbRetour]) + "/" + nameDialog
if DEBUG: print( "THE DIALOGS ARE CONTAINED IN THE FILE : ", dialogfile )
print( "THE DIALOGS ARE CONTAINED IN THE FILE : ", dialogfile )
nbdiag = 0
diagdata = fxconv.Structure()
@ -193,7 +192,7 @@ def get_tile_map_data(input, output, params, target, xmin, ymin, xmax, ymax):
datavalid = data["layers"][i]
if datavalid["name"]=="Background":
layer_background = i
if DEBUG: print( "Background Tile Data in layer : ", layer_background)
print( "Background Tile Data in layer : ", layer_background)
break
elif i==nbTilelayer:
print( "ERROR : No Background layer data !!!" )
@ -211,10 +210,10 @@ def get_tile_map_data(input, output, params, target, xmin, ymin, xmax, ymax):
datavalid = data["layers"][i]
if datavalid["name"]=="Foreground":
layer_foreground = i
if DEBUG: print( "Foreground Tile Data in layer : ", layer_foreground)
print( "Foreground Tile Data in layer : ", layer_foreground)
break
elif i==nbTilelayer:
print( "ERROR : No Foreground layer data !!!" )
printf( "ERROR : No Foreground layer data !!!" )
layer_data = bytes()
layer = data["layers"][layer_foreground]
@ -228,11 +227,11 @@ def get_tile_map_data(input, output, params, target, xmin, ymin, xmax, ymax):
def get_extra_map_data(input, output, params, target, xmin, ymin, xmax, ymax):
if DEBUG: print( "WE ARE COMPUTING THE EXTRA DATA OF THE MAP : ", input )
print( "WE ARE COMPUTING THE EXTRA DATA OF THE MAP : ", input )
data = json.load(open(input, "r"))
nblayer = ["id" in i for i in data["layers"]].count(True) - 1
if DEBUG: print( "I found ", nblayer, " of extradata")
print( "I found ", nblayer, " of extradata")
#index of the various layers (may change from one map to another)
layer_extradata = 0
@ -242,7 +241,7 @@ def get_extra_map_data(input, output, params, target, xmin, ymin, xmax, ymax):
datavalid = data["layers"][i]
if datavalid["name"]=="ExtraData":
layer_extradata = i
if DEBUG: print( "Extra Data in layer : ", layer_extradata)
print( "Extra Data in layer : ", layer_extradata)
break
elif i==nblayer:
print( "ERROR : No ExtraData layer data !!!" )
@ -273,7 +272,6 @@ def get_extra_map_data(input, output, params, target, xmin, ymin, xmax, ymax):
path_length = 0
xdata = None
ydata = None
face_type = "MALE"
#we now fill all the properties of this item
for j in i["properties"]:
@ -283,45 +281,42 @@ def get_extra_map_data(input, output, params, target, xmin, ymin, xmax, ymax):
elif j["name"]=="needAction": needAction = j[ "value" ]
else:
#Extra properties for NPCs (path and face)
#Extra properties for NPCs (path)
if tpe=="NPC":
if j["name"]=="face":
face_type = j["value"]
elif j["name"]=="hasPath":
if j["name"]=="hasPath":
pathID = None
path = j[ "value" ]
if path==1:
if DEBUG: print( "PNJ has path - NOW LOOKING FOR RELEVANT DATA" )
print( "PNJ has path - NOW LOOKING FOR RELEVANT DATA" )
# we start looking for path data with first the ID of the path Object
for u in i["properties"]:
if u["name"]=="path":
pathID = u[ "value" ]
if DEBUG: print( "path ID is identified : ID= ", pathID )
print( "path ID is identified : ID= ", pathID )
for v in layer["objects"]:
if v[ "id" ] == pathID:
if DEBUG: print( "path data found : " )
print( "path data found : " )
xdata = bytes()
ydata = bytes()
for w in v[ "polyline" ]:
path_length = path_length + 1
if DEBUG: print( "X= ", w[ "x" ], " Y= ", w[ "y" ] )
print( "X= ", w[ "x" ], " Y= ", w[ "y" ] )
xdata += fxconv.u16( int( w[ "x" ] ) )
ydata += fxconv.u16( int( w[ "y" ] ) )
else:
if DEBUG: print( "PNJ has no Path" )
print( "PNJ has no Path" )
else:
print( "UNIDENTIFIED PROPERTY : ", j["name"])
if DEBUG:
print( "OBJECT X= ", x, " Y= ", y, "STR= ", dialogID )
print( " Type= ", tpe, " Name= ", nme, "Face =", face_type)
print( " Action?= ", needAction )
print( "OBJECT X= ", x, " Y= ", y, "STR= ", dialogID )
print( " Type= ", tpe, " Name= ", nme )
print( " Action?= ", needAction )
@ -329,7 +324,6 @@ def get_extra_map_data(input, output, params, target, xmin, ymin, xmax, ymax):
structData += fxconv.u32( int(y) )
structData += fxconv.string( nme )
structData += fxconv.string( tpe )
structData += fxconv.string(face_type)
structData += fxconv.u32( int(dialogID) )
structData += fxconv.u32( int(needAction) )
@ -351,8 +345,9 @@ def get_extra_map_data(input, output, params, target, xmin, ymin, xmax, ymax):
#else we do nothing (yet)
else:
if DEBUG: print( "Skip this object" )
print( "Skip this object" )
return nbExtraData, structData
@ -377,16 +372,16 @@ def convert_font(input, output, params, target):
def convert_dialogs(input, output, params, target):
if DEBUG: print( "WE ARE COMPUTING THE DIALOGS FROM : ", input )
print( "WE ARE COMPUTING THE DIALOGS FROM : ", input )
data = json.load(open(input, "r"))
structDialogs = fxconv.Structure()
nbdialogs = 0
for d in data["dialogs"]:
if DEBUG: print( int(d[ "ID" ]))
print( int(d[ "ID" ]))
# print( d[ "dialog" ] )
if DEBUG: print( int(d[ "isQuestion" ]) )
print( int(d[ "isQuestion" ]) )
# print( d[ "choice" ].replace('$', chr(0)) )
# print( d[ "conclusion1" ] )
# print( int(d[ "next1" ] ) )
@ -407,4 +402,4 @@ def convert_dialogs(input, output, params, target):
return nbdialogs, structDialogs
#fxconv.elf(structDialogs, output, "_" + params["name"], **target)
#fxconv.elf(structDialogs, output, "_" + params["name"], **target)

View file

@ -1,5 +1,5 @@
<?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="8" nextobjectid="14">
<map version="1.10" tiledversion="1.10.1" orientation="orthogonal" renderorder="right-down" width="48" height="24" tilewidth="8" tileheight="8" infinite="0" nextlayerid="8" nextobjectid="14">
<editorsettings>
<export target="level0.json" format="json"/>
</editorsettings>
@ -117,7 +117,6 @@
<object id="12" name="PNJ3" type="NPC" x="267.25" y="125.75">
<properties>
<property name="dialogID" type="int" value="12"/>
<property name="face" value="FEMALE"/>
<property name="hasPath" type="int" value="1"/>
<property name="needAction" type="int" value="1"/>
<property name="path" type="object" value="13"/>
@ -127,7 +126,6 @@
<object id="2" name="PNJ2" type="NPC" x="164" y="132">
<properties>
<property name="dialogID" type="int" value="5"/>
<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"/>
@ -137,7 +135,6 @@
<object id="10" name="PNJ1" type="NPC" x="252" y="164">
<properties>
<property name="dialogID" type="int" value="7"/>
<property name="face" value="MILKMAN"/>
<property name="hasPath" type="int" value="1"/>
<property name="needAction" type="int" value="1"/>
<property name="path" type="object" value="9"/>

View file

@ -1,5 +1,5 @@
<?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="5" nextobjectid="4">
<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="4">
<properties>
<property name="dialogFile" type="file" value="DialogsLvl1.json"/>
</properties>
@ -100,7 +100,6 @@
<object id="2" name="Gardien" type="NPC" x="303.636" y="117.273">
<properties>
<property name="dialogID" type="int" value="1"/>
<property name="face" value="POLICE"/>
<property name="hasPath" type="int" value="1"/>
<property name="needAction" type="int" value="1"/>
<property name="path" type="object" value="3"/>

View file

@ -1,5 +1,5 @@
<?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="5" nextobjectid="5">
<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="5">
<properties>
<property name="dialogFile" type="file" value="DialogsLvl2.json"/>
</properties>
@ -37,7 +37,7 @@
<data encoding="csv">
250,251,252,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,297,298,299,300,0,0,0,225,226,227,228,225,226,227,228,0,0,0,0,0,273,274,275,276,0,0,0,
274,275,276,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,201,202,203,204,0,0,0,0,249,250,251,252,249,250,251,252,0,0,258,259,263,264,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,225,226,227,228,0,0,0,0,273,274,275,276,273,274,275,276,0,0,282,307,311,288,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,225,226,227,228,0,0,0,0,273,274,275,276,273,274,275,276,0,0,282,3,3,288,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,249,250,251,252,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,201,202,203,204,0,0,0,0,0,0,0,0,0,0,0,0,0,273,274,275,276,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,225,226,227,228,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

1
clean
View file

@ -6,7 +6,6 @@ cd ..
rm -r build-cg
rm -r build-cg-push
rm -r build-fx
rm -r build-fxg3a
rm *.g1a
rm *.g3a

View file

@ -2,55 +2,27 @@
#define CONFIG_H
#define USB_FEATURE 0
#define DEBUGMODE 0
#include <gint/display.h>
/* Enable GrayMode on either FX and FX_G3A targets */
#if GINT_RENDER_MONO && defined(COLOR2BIT)
#if !defined(FXCG50) && defined(COLOR2BIT)
#define GRAYMODEOK 1
#endif
#define USB_FEATURE 0
#define DEBUGMODE 0
#if GINT_RENDER_RGB
/* The tile size */
#ifdef FXCG50
#define T_HEIGHT 16
#define T_WIDTH 16
/* The size of a pixel */
#define PXSIZE 2
#define PATH_COLOR C_RED
/* The size of the player */
#define P_WIDTH 16
#define P_HEIGHT 16
#else
/* The tile size */
#define T_HEIGHT 8
#define T_WIDTH 8
/* The pixel size */
#define PXSIZE 1
#define PATH_COLOR C_BLACK
/* The player size */
#define P_WIDTH 8
#define P_HEIGHT 8
#endif
/* SPEED should NOT be 8 or bigger: it may cause bugs when handling
* collisions! */
#define SPEED (PXSIZE*2)
/* The face size (in the dialogs) */
#define F_WIDTH (32*PXSIZE)
#define F_HEIGHT (32*PXSIZE)
/* the color of the text to go to the next dialog phase */
/* it improves readability to have something lighter */
#if GRAYMODEOK || (GINT_RENDER_RGB && !defined(COLOR1BIT))
#define NEXT_COLOR C_DARK
#ifdef FXCG50
#define PXSIZE 2
#else
#define NEXT_COLOR C_BLACK
#define PXSIZE 1
#endif
#endif

View file

@ -25,11 +25,20 @@ extern font_t fontRPG;
uint32_t *lightVRAMcurrent, *darkVRAMcurrent;
#endif //GRAYMODEOK
/* the color of the text to go to the next dialog phase */
/* it improves readability to have somathing lighter */
#if GRAYMODEOK || (defined(FXCG50) && !defined(COLOR1BIT))
#define NEXT_COLOR C_DARK
#else
#define NEXT_COLOR C_BLACK
#endif
void blit() {
void blit()
{
dupdate();
#if GRAYMODEOK && !GINT_HW_CG
#if GRAYMODEOK
dgray_getvram( &lightVRAMnext, &darkVRAMnext );
dgray_getscreen( &lightVRAMcurrent, &darkVRAMcurrent );
@ -39,14 +48,13 @@ void blit() {
}
int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
int call_before_end(Game *game, unsigned int i),
bool start_anim,
bool end_anim,
void for_each_screen(Game *game, unsigned int i),
int line_duration, bool update_screen, unsigned int start_i,
bool wait_continue) {
text = events_parse_string(&game->handler, text);
int showtext_opt(Game *game, bopti_image_t *face, char *text,
int call_before_end(Game *game, unsigned int i),
bool start_anim,
bool end_anim,
void for_each_screen(Game *game, unsigned int i),
int line_duration, bool update_screen, unsigned int start_i,
bool wait_continue) {
dfont(&FONT_USED);
unsigned int i, n, y = PXSIZE, l = 0;
int line_max_chars, return_int = 0;
@ -59,7 +67,7 @@ int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
/* Redrawing the entire screen, because maybe there was no dialog
displayed before. */
update_npc(game);
game_draw(game);
draw(game);
/* Fill the dialog box with white */
drect(0, 0, DWIDTH, i*PXSIZE, C_WHITE);
@ -79,7 +87,7 @@ int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
}else{
/* Here I'm drawing the same as if start_anim is true, but whitout
* making an animation. */
game_draw(game);
draw(game);
drect(0, 0, DWIDTH, BOX_HEIGHT*PXSIZE, C_WHITE);
drect(0, BOX_HEIGHT*PXSIZE, DWIDTH, (BOX_HEIGHT+1)*PXSIZE, C_BLACK);
dimage(4*PXSIZE, 2*PXSIZE, face);
@ -140,12 +148,7 @@ int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
if(l>=max_lines_amount-1){
/* If we drew one entire screen. */
/* Wait that the SHIFT key is pressed if we should. */
if(wait_continue){
while(getkey_opt(GETKEY_DEFAULT & ~GETKEY_MOD_SHIFT &
~GETKEY_MOD_ALPHA, NULL).key != KEY_SHIFT){
sleep();
}
}
if(wait_continue) while(getkey_opt(GETKEY_DEFAULT & ~GETKEY_MOD_SHIFT & ~GETKEY_MOD_ALPHA, NULL).key != KEY_SHIFT) sleep();
/* Clear the text area. */
drect(BOX_HEIGHT*PXSIZE, 0, DWIDTH, (BOX_HEIGHT-1)*PXSIZE-2,
C_WHITE);
@ -169,12 +172,7 @@ int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
dtext(BOX_HEIGHT*PXSIZE, y, NEXT_COLOR, "[SHIFT] : suite...");
/* Update the screen and wait for SHIFT being pressed, if needed. */
if(update_screen) blit();
if(wait_continue){
while(getkey_opt(GETKEY_DEFAULT & ~GETKEY_MOD_SHIFT &
~GETKEY_MOD_ALPHA, NULL).key != KEY_SHIFT){
sleep();
}
}
if(wait_continue) while(getkey_opt( GETKEY_DEFAULT & ~GETKEY_MOD_SHIFT & ~GETKEY_MOD_ALPHA, NULL).key != KEY_SHIFT) sleep();
}
if(call_before_end) return_int = call_before_end(game, i);
if(end_anim){
@ -182,11 +180,11 @@ int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
for(i=BOX_HEIGHT;i>0;i--){
/* It is the same as the start animation. */
update_npc(game);
game_draw(game);
draw(game);
drect(0, 0, DWIDTH, i*PXSIZE, C_WHITE);
drect(0, i*PXSIZE, DWIDTH, (i+1)*PXSIZE, C_BLACK);
dsubimage(4*PXSIZE, 2*PXSIZE, face, 0, 0, F_WIDTH, (i-8)*PXSIZE,
DIMAGE_NONE);
DIMAGE_NONE);
dupdate();
@ -197,12 +195,12 @@ int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
return return_int;
}
void dialogs_text(Game *game, bopti_image_t *face, char *text,
bool dialog_start, bool dialog_end) {
void showtext_dialog(Game *game, bopti_image_t *face, char *text,
bool dialog_start, bool dialog_end) {
/* Run showtext_opt with some default values. It makes it easier to use in
* simple dialogs. */
dialogs_text_opt(game, face, text, NULL, dialog_start, dialog_end, NULL, 100,
true, 0, true);
showtext_opt(game, face, text, NULL, dialog_start, dialog_end, NULL, 100,
true, 0, true);
}
@ -303,9 +301,9 @@ int _choice_call_before_end(Game *game, [[maybe_unused]] unsigned int org_i) {
for(i=DWIDTH/8+1;i>0;i--){
/* I'm drawing the same box as on the start animation */
update_npc(game);
game_draw(game);
dialogs_text_opt(game, _face, _text, NULL, false, false, NULL, 0, false,
_i, false);
draw(game);
showtext_opt(game, _face, _text, NULL, false, false, NULL, 0, false,
_i, false);
drect(0, (BOX_HEIGHT+1)*PXSIZE+1, i*(DWIDTH/8),
(BOX_HEIGHT+CHOICE_BOX_HEIGHT)*PXSIZE, C_WHITE);
drect(i*(DWIDTH/8), BOX_HEIGHT*PXSIZE, i*(DWIDTH/8)+PXSIZE-1,
@ -321,9 +319,9 @@ int _choice_call_before_end(Game *game, [[maybe_unused]] unsigned int org_i) {
return selected;
}
int dialogs_ask(Game *game, bopti_image_t *face, char *text, bool start,
bool end, char *choices, int choices_amount,
int default_choice) {
int showtext_dialog_ask(Game *game, bopti_image_t *face, char *text, bool start,
bool end, char *choices, int choices_amount,
int default_choice) {
/* Put some arguments in global pointers and variables to make them
* accessible by _choice_call_before_end. */
_choices = choices;
@ -333,16 +331,16 @@ int dialogs_ask(Game *game, bopti_image_t *face, char *text, bool start,
_text = text;
/* Run showtext_opt and return his return value (the return value of
*_choice_call_before_end) */
return dialogs_text_opt(game, face, text, _choice_call_before_end, start,
end, _choice_screen_call, 100, true, 0, true);
return showtext_opt(game, face, text, _choice_call_before_end, start, end,
_choice_screen_call, 100, true, 0, true);
}
void dialogs_initiate_sequence(Game *game, bopti_image_t *face,
uint32_t dialogNumber) {
Dialog *currentDiag = &game->map_level->dialogs[dialogNumber];
void initiate_dialog_sequence(Game *game, bopti_image_t *face, uint32_t dialogNumber )
{
Dialog *currentDiag = &game->map_level->dialogs[ dialogNumber ];
/* we collect the information */
char *text = currentDiag->dialog;
@ -356,23 +354,27 @@ void dialogs_initiate_sequence(Game *game, bopti_image_t *face,
int isQuestion = currentDiag->isQuestion;
/* we treat the action - i.e. we show a dialog */
if (isQuestion == 1){
/* we have to manage a question */
int answer = dialogs_ask(game, face, text, true, true,
choices, 2, 0);
if (isQuestion == 1) /* we have to manage a question */
{
int answer = showtext_dialog_ask( game, face, text, true, true, choices, 2, 0 );
/* TO DO we need to split the strings conclusion1 and conclusion2 */
/* to extract the "gift" part */
if(answer==0){
dialogs_text(game, face, conclusion1, true, true);
if (next1!=-1) dialogs_initiate_sequence(game, face, next1);
}else{
dialogs_text(game, face, conclusion2, true, true);
if (next2!=-1) dialogs_initiate_sequence(game, face, next2);
if (answer==0)
{
showtext_dialog( game, face, conclusion1, true, true );
if (next1!=-1) initiate_dialog_sequence( game, face, next1 );
}
}else{
dialogs_text(game, face, text, true, true);
if (nextOther!=-1) dialogs_initiate_sequence(game, face, nextOther);
else
{
showtext_dialog( game, face, conclusion2, true, true );
if (next2!=-1) initiate_dialog_sequence( game, face, next2 );
}
}
else
{
showtext_dialog( game, face, text, true, true );
if (nextOther!=-1) initiate_dialog_sequence( game, face, nextOther );
}
}

View file

@ -5,9 +5,11 @@
#include <string.h>
#include "game.h"
#include "map.h"
#include "config.h"
/* dialogs_text_opt()
#define F_WIDTH (32*PXSIZE)
#define F_HEIGHT (32*PXSIZE)
/* showtext_opt()
*
* Show some text in a box with word wrap for dialogs.
*
@ -35,17 +37,17 @@
* wait_continue: If I should wait that EXE is pressed after drawing a page.
*/
int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
int call_before_end(Game *game, unsigned int i),
bool start_anim,
bool end_anim,
void for_each_screen(Game *game, unsigned int i),
int line_duration, bool update_screen,
unsigned int start_i, bool wait_continue);
int showtext_opt(Game *game, bopti_image_t *face, char *text,
int call_before_end(Game *game, unsigned int i),
bool start_anim,
bool end_anim,
void for_each_screen(Game *game, unsigned int i),
int line_duration, bool update_screen, unsigned int start_i,
bool wait_continue);
/* dialogs_text()
/* showtext_dialog()
*
* Calls dialogs_text_opt with default parameters.
* Calls showtext_opt with default parameters.
*
* game: The game struct of the current game.
* face: A bopti_image_t of the face of the person who's saying this
@ -58,12 +60,12 @@ int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
* shown at the end of showtext_opt.
*/
void dialogs_text(Game *game, bopti_image_t *face, char *text,
bool dialog_start, bool dialog_end);
void showtext_dialog(Game *game, bopti_image_t *face, char *text,
bool dialog_start, bool dialog_end);
/* dialogs_ask()
/* showtext_dialog_ask()
*
* Like dialogs_text, but lets the user choose between multiple possible
* Like showtext_dialog, but lets the user choose between multiple possible
* choices after displaying the text.
*
* game: The game struct of the current game.
@ -83,12 +85,10 @@ void dialogs_text(Game *game, bopti_image_t *face, char *text,
* default_choice: The choice choosen by default when the dialog just opened.
*/
int dialogs_ask(Game *game, bopti_image_t *face, char *text, bool start,
bool end, char *choices, int choices_amount,
int default_choice);
int showtext_dialog_ask(Game *game, bopti_image_t *face, char *text, bool start,
bool end, char *choices, int choices_amount,
int default_choice);
/* TODO: Doc. */
void dialogs_initiate_sequence(Game *game, bopti_image_t *face,
uint32_t dialogNumber);
void initiate_dialog_sequence(Game *game, bopti_image_t *face, uint32_t dialogNumber );
#endif

View file

@ -1,64 +0,0 @@
#ifndef EVENTS_H
#define EVENTS_H
/* The max amount of variables that can be bound. */
#define MAX_VARIABLES 32
/* The max. size of the message buffer.
* WARNING: Bigger messages will be truncated! */
#define MESSAGE_BUFFER_SZ 1024
/* The maximal size of a token. Bigger tokens will be truncated. */
#define TOKEN_MAX_SZ 1024
typedef struct {
int *variables[MAX_VARIABLES];
char *var_names[MAX_VARIABLES];
unsigned int vars;
} EventHandler;
typedef enum {
T_NULL,
T_VAR_EDIT,
T_AMOUNT
} Token;
typedef enum {
OP_NULL,
OP_SET,
OP_ADD,
OP_SUB,
OP_DIV,
OP_MUL,
OP_MOD,
OP_AMOUNT
} Operation;
/* events_init_handler()
*
* Initialize an event handler.
* handler: The Event handler to initialize.
*/
void events_init_handler(EventHandler *handler);
/* events_bind_variable()
*
* Bind a variable. Binding a variable allows it to be modified by messages
* passed to the event handler using tags written as following:
* `variable+number` (The backticks delimit the tag). Available operators:
* '=': Assign a value to the variable.
* '+': Addition.
* '-': Substraction.
* '*': Multiplication.
* '/': Division.
* '%': Modulo.
* handler: The event handler.
* var: A pointer to the variable to bind.
* name: The name of the variable. This is the name that will be used to
* refer to this variable in a tag.
*/
int events_bind_variable(EventHandler *handler, int *var, char *name);
/* events_parse_string()
* handler: The event handler.
* message: The message to parse.
*/
char *events_parse_string(EventHandler *handler, char *message);
#endif

View file

@ -27,16 +27,18 @@ void game_logic(Game *game) {
update_npc( game );
/* we check if interactions are possible close to the player */
for( uint32_t i=0; i<game->map_level->nbextradata; i++ ){
for( uint32_t i=0; i<game->map_level->nbextradata; i++ )
{
/* simple distance check along X and Y axis */
/* Be careful to use world coordinates, not local (i.e.map) ones */
if ((abs((int) game->player.wx -
if ( (abs((int) game->player.wx -
(int) game->map_level->extradata[i].x*PXSIZE )
< MAX_INTERACTION_DISTANCE*PXSIZE)
&& (abs((int) game->player.wy -
(int) game->map_level->extradata[i].y*PXSIZE )
< MAX_INTERACTION_DISTANCE*PXSIZE)
&& strcmp(game->map_level->extradata[i].type, "NPC") != 0){
&& strcmp( game->map_level->extradata[i].type, "NPC") !=0 )
{
/* the player can do something */
game->player.canDoSomething = true;
/* we mark the action for futur treatment in player_action() */
@ -47,16 +49,18 @@ void game_logic(Game *game) {
}
}
for(uint32_t i=0; i<nbNPC; i++){
for( uint32_t i=0; i<nbNPC; i++ )
{
/* simple distance check along X and Y axis */
/* Be careful to use world coordinates, not local (i.e.map) ones */
if ((abs((int) game->player.wx -
if ( (abs((int) game->player.wx -
(int) npcRPG[i].curx*PXSIZE )
< MAX_INTERACTION_DISTANCE*PXSIZE)
&& (abs((int) game->player.wy -
(int) npcRPG[i].cury*PXSIZE )
< MAX_INTERACTION_DISTANCE*PXSIZE)
&& strcmp( game->map_level->extradata[i].type, "NPC") !=0){
&& strcmp( game->map_level->extradata[i].type, "NPC") !=0 )
{
/* the player can do something */
game->player.canDoSomething = true;
/* we mark the action for futur treatment in player_action() */
@ -76,31 +80,33 @@ void game_logic(Game *game) {
}
void game_render_indicator(Game *game) {
void render_indicator(Game *game)
{
/* 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 */
dimage(5, 5, &SignAction_img);
}
void game_draw(Game *game) {
void draw(Game *game) {
/* Draw everything. */
dclear(C_WHITE);
map_render_by_layer(game, BACKGROUND);
npc_draw(game);
render_map_by_layer(game, BACKGROUND);
npc_draw( game );
player_draw(game);
map_render_by_layer(game, FOREGROUND);
game_render_indicator(game);
dprint(8, 8, C_BLACK, "Lifes: %d", game->player.life);
dprint(8, 16, C_BLACK, "Mana: %d", game->mana);
render_map_by_layer(game, FOREGROUND);
render_indicator( game );
}
/* Key management */
void game_get_inputs(Game *game) {
clearevents();
void get_inputs(Game *game) {
key_event_t ev;
while((ev = pollevent()).type != KEYEV_NONE){
/**/
}
/* Key binding for the Player action */
@ -137,3 +143,4 @@ void game_get_inputs(Game *game) {
#endif //USB_FEATURE
}

View file

@ -70,7 +70,6 @@ typedef struct {
char *name;
/* its class (NPC, SGN, INFO, ... )*/
char *type;
char *face;
/* the ID of the first element of the dialog */
/* (to be aligned with "dialogs.json" IDs)*/
@ -151,27 +150,15 @@ typedef struct {
/* (Mibi88) TODO: Describe what this function is doing. */
void game_logic(Game *game);
/* game_draw()
*
* Draws everything on screen.
* game: The game struct.
*/
void game_draw(Game *game);
/* Draws everything on screen. */
void draw(Game *game);
/* game_render_indicator()
*
* This render a small sign on the upper left corner of the screen
* if the player can do an action
* game: The game struct.
*/
void game_render_indicator(Game *game);
/* This render a small sign on the upper lecft corner of the screen */
/* if the player can do an action */
void render_indicator(Game *game);
/* game_get_inputs()
*
* Handle key presses.
* game: The game struct.
*/
void game_get_inputs(Game *game);
/* Handle key presses. */
void get_inputs(Game *game);
#endif

View file

@ -42,7 +42,7 @@ Game game = {
, false, false, false
};
/* screen capture management code. TODO: Clean this up! */
/* screen capture management code */
#if USB_FEATURE
@ -128,9 +128,9 @@ int main(void) {
dclear(C_WHITE);
/* render the map */
game_draw(&game);
draw(&game);
#if DEBUGMODE && GINT_RENDER_RGB
#if DEBUGMODE && FXCG50
if (game.debug_map)
{
dfont( NULL );
@ -181,7 +181,7 @@ int main(void) {
#endif
/* Management of the inputs */
game_get_inputs(&game);
get_inputs(&game);
/* Run the game at max. 50fps */
while(game.frame_duration < 20) sleep();
/* Reset frame_duration for the next frame */

View file

@ -8,7 +8,7 @@ extern Map *worldRPG[];
//extern ExtraData *extraRPG[];
void map_render(Game *game) {
void render_map(Game *game) {
Map *map_level = game->map_level;
Player *player = &game->player;
@ -104,7 +104,7 @@ void map_render(Game *game) {
}
}
void map_render_by_layer(Game *game, int layer) {
void render_map_by_layer(Game *game, int layer) {
Map *map_level = game->map_level;
Player *player = &game->player;
@ -194,7 +194,7 @@ void map_render_by_layer(Game *game, int layer) {
}
}
short int map_get_tile(Game *game, int x, int y, int l) {
short int get_tile(Game *game, int x, int y, int l) {
Map *map_level = game->map_level;
@ -204,7 +204,7 @@ short int map_get_tile(Game *game, int x, int y, int l) {
map_level->layers[l][y * map_level->w + x] : MAP_OUTSIDE;
}
short int map_get_walkable(Game *game, int x, int y) {
short int get_walkable(Game *game, int x, int y) {
Map *map_level = game->map_level;
/* Get the tile at (x, y). Returns the tile ID or MAP_OUTSIDE if she's not
@ -214,25 +214,26 @@ short int map_get_walkable(Game *game, int x, int y) {
}
/* return the pointer to the map containing the given position */
Map *map_get_for_coordinates( Game *game, int x, int y )
Map *get_map_for_coordinates( Game *game, int x, int y )
{
/* check if the current map contains the point */
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)
return game->map_level;
}
/* else we check in worldRPG if there is a mal containing that point */
int i = 0;
Map *current = worldRPG[i];
do{
do
{
if (x>= (int)current->xmin && x< (int)current->xmax &&
y>= (int)current->ymin && y< (int)current->ymax)
return current;
i++;
current = worldRPG[i];
}while (current!=NULL);
}
while (current!=NULL);
/* else we return NULL cause the point is a not within a map */
return NULL;
}
}

View file

@ -19,48 +19,21 @@
/* map_render()
*
* Draws the map map on the entire screen to be viewed by the player player.
* game: The game struct.
*/
void map_render(Game *game);
/* Draws the map map on the entire screen to be viewed by the player player. */
void render_map(Game *game);
/* map_render_by_layer()
*
* Draws the map layer on the entire screen to be viewed by the player player.
* game: The game struct.
* layer: The layer to render.
/* Draws the map layer on the entire screen to be viewed by the player player.
*/
void map_render_by_layer(Game *game, int layer);
void render_map_by_layer(Game *game, int layer);
/* map_get_tile()
*
* Get the tile at (x, y) of the map map. If the tile is located outside of the
* screen, MAP_OUTSIDE is returned.
* game: The game struct.
* x: The coordinates of the tile.
* y: The coordinates of the tile.
* l: The layer of the tile.
*/
short int map_get_tile(Game *game, int x, int y, int l);
/* Get the tile at (x, y) of the map map. If the tile is located outside of the
* screen, MAP_OUTSIDE is returned. */
short int get_tile(Game *game, int x, int y, int l);
/* map_get_walkable()
*
* Returns what is in the walkable layer at (x, y).
* game: The game struct.
* x: The coordinates of the tile.
* y: The coordinates of the tile.
*/
short int map_get_walkable(Game *game, int x, int y);
/* Returns what is in the walkable layer at (x, y). */
short int get_walkable(Game *game, int x, int y);
/* map_get_for_coordinates()
*
* return the pointer to the map containing the given position.
* game: The game struct.
* x: The coordinates to look at.
* y: The coordinates to look at.
*/
Map* map_get_for_coordinates(Game *game, int x, int y );
/* return the pointer to the map containing the given position */
Map* get_map_for_coordinates(Game *game, int x, int y );
#endif

View file

@ -1,6 +1,6 @@
#include "memory.h"
bool memory_is_in(short int *array, short int array_length, short int item) {
bool is_in(short int *array, short int array_length, short int item) {
short int i;
for(i=0;i<array_length;i++){
if(array[i] == item){

View file

@ -2,14 +2,8 @@
#define MEMORY_H
#include <stdbool.h>
/* memory_is_in()
*
* returns true if item is in array.
* array: The array to search in.
* array_length: The length of the array.
* item: The item to search for.
*/
bool memory_is_in(short int *array, short int array_length, short int item);
bool is_in(short int *array, short int array_length, short int item);
#endif

View file

@ -14,6 +14,15 @@
extern bopti_image_t demo_PNJ_img;
/* the color of the text to go to the next dialog phase */
/* it improves readability to have somathing lighter */
#if defined(FXCG50)
#define PATH_COLOR C_RED
#else
#define PATH_COLOR C_BLACK
#endif
NPC *npcRPG;
uint32_t nbNPC = 0;
@ -97,7 +106,6 @@ void reload_npc(Game *game)
npcRPG[currentNPC].xpath = Data->xpath;
npcRPG[currentNPC].ypath = Data->ypath;
npcRPG[currentNPC].paused = false;
npcRPG[currentNPC].face = Data->face;
currentNPC++;
}
}

View file

@ -31,8 +31,6 @@ typedef struct
/* is the current NPC in pause (during dialog) */
bool paused;
char *face;
} NPC;

View file

@ -6,28 +6,6 @@
#include "npc.h"
#include <gint/display.h>
#define FACES 4
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_female;
extern bopti_image_t npc_milkman;
extern bopti_image_t npc_police;
extern bopti_image_t SGN_Icon_img;
extern bopti_image_t INFO_Icon_img;
const struct Face faces[FACES] = {
{"MALE", &npc_male},
{"FEMALE", &npc_female},
{"MILKMAN", &npc_milkman},
{"POLICE", &npc_police}
};
const char one_px_mov[8] = {
0, -1, /* Up */
0, 1, /* Down */
@ -105,13 +83,18 @@ void player_move(Game *game, Direction direction) {
player->wy = game->map_level->ymin * PXSIZE + player->y;
}
void player_action(Game *game) {
register size_t i;
/* already doing something (action IS NOT with an NPC) */
if(game->player.isDoingAction) return;
if(game->player.canDoSomething && !game->player.isInteractingWithNPC){
/* we can do something */
extern bopti_image_t demo_player_img;
extern bopti_image_t NPC_Icon_img;
extern bopti_image_t SGN_Icon_img;
extern bopti_image_t INFO_Icon_img;
void player_action(Game *game) {
if( game->player.isDoingAction ) return; /* alreday doing something (action IS NOT with an NPC ) */
if( game->player.canDoSomething && !game->player.isInteractingWithNPC ) /* we can do something */
{
/* we indicate that the player is occupied */
game->player.isDoingAction = true;
@ -123,33 +106,23 @@ void player_action(Game *game) {
/* we use the correct image as per the class of the item */
if (strcmp("INFO", currentData->type)==0){
if (strcmp("INFO", currentData->type)==0)
face = &INFO_Icon_img;
}else if (strcmp("SGN", currentData->type)==0){
//else if (strcmp("NPC", currentData->type)==0)
// face = &NPC_Icon_img;
else if (strcmp("SGN", currentData->type)==0)
face = &SGN_Icon_img;
}else{
/* It's a NPC */
/* (Mibi88) TODO: Use string hash + strcmp if the hashes match for
* fast string comparison. */
face = NULL;
for(i=0;i<FACES;i++){
struct Face current_face = faces[i];
if(!strcmp(current_face.name, currentData->face)){
face = current_face.face;
}
}
if(!face) face = &npc_male;
}
else face = &demo_player_img;
uint32_t dialogStart = currentData->dialogID;
dialogs_initiate_sequence(game, face, dialogStart);
initiate_dialog_sequence( game, face, dialogStart );
/* when done we release the occupied status of the player */
game->player.isDoingAction = false;
}else if(game->player.canDoSomething && game->player.isInteractingWithNPC){
/* we can do something (action IS with an NPC) */
}
else if( game->player.canDoSomething && game->player.isInteractingWithNPC ) /* we can do something (action IS with an NPC ) */
{
/* we indicate that the player is occupied */
game->player.isDoingAction = true;
@ -157,28 +130,14 @@ void player_action(Game *game) {
/* we use the correct image as per the class of the item */
ExtraData *currentData = &game->map_level->extradata[game->player.whichAction];
bopti_image_t *face = &npc_male;
/* It's a NPC */
/* (Mibi88) TODO: Use string hash + strcmp if the hashes match for
* fast string comparison. */
face = NULL;
for(i=0;i<FACES;i++){
struct Face current_face = faces[i];
if(!strcmp(current_face.name, currentNPC->face)){
face = current_face.face;
}
if(!face) face = &npc_male;
}
dtext(2, 64, C_BLACK, currentData->type);
bopti_image_t *face = &NPC_Icon_img;
uint32_t dialogStart = currentNPC->dialogID;
/* we set this NPC to paused to avoid changing its position while
* talking (the rest of the NPCs pursue their action) */
/* we setr this NPC to paused to avoid changing its position while talking (the rest of the NPCs pursue their action)*/
currentNPC->paused = true;
dialogs_initiate_sequence(game, face, dialogStart);
initiate_dialog_sequence( game, face, dialogStart );
/* when done we release the occupied status of the player */
game->player.isDoingAction = false;
@ -215,13 +174,15 @@ bool player_collision(Game *game, Direction direction,
/* check where the player is expected to go on the next move */
/* if outside the map, we check if there is a map on the other */
/* side of the current map*/
if (map_get_walkable(game, player_tile_x, player_tile_y) == MAP_OUTSIDE){
if (get_walkable(game, player_tile_x, player_tile_y) == MAP_OUTSIDE)
{
// we compute the expected world coordinates accordingly
// while taking care of the scaling between fx and cg models (PXSIZE)
int worldX = (player->wx+dx) / PXSIZE;
int worldY = (player->wy+dy) / PXSIZE;
Map *map = map_get_for_coordinates(game, worldX, worldY);
if (map!=NULL && map!=game->map_level){
Map *map = get_map_for_coordinates(game, worldX, worldY );
if (map!=NULL && map!=game->map_level)
{
Map *backupmap = game->map_level;
int backupx = player->x;
int backupy = player->y;
@ -236,7 +197,7 @@ bool player_collision(Game *game, Direction direction,
player->x = (worldX - map->xmin ) * PXSIZE;
player->y = (worldY - map->ymin ) * PXSIZE;
int on_walkable = map_get_walkable(game, player->x/T_WIDTH,
int on_walkable = get_walkable(game, player->x/T_WIDTH,
player->y/T_HEIGHT);
int speed = (on_walkable >= 0 && on_walkable < WALKABLE_TILE_MAX) ?
@ -256,7 +217,7 @@ bool player_collision(Game *game, Direction direction,
/* we update the list of NPCs in the current map */
/* to follow the trajectories */
reload_npc(game);
reload_npc( game );
return false;
}
@ -270,7 +231,7 @@ bool player_collision(Game *game, Direction direction,
if(player_tile_y < 0) 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 = get_walkable(game, player_tile_x, player_tile_y);
int speed = (on_walkable >= 0 && on_walkable < WALKABLE_TILE_MAX) ?
walkable_speed[on_walkable] : 0;

View file

@ -1,8 +1,21 @@
#ifndef PLAYER_H
#define PLAYER_H
/* The size of the player. */
#ifdef FXCG50
#define P_WIDTH 16
#define P_HEIGHT 16
#else
#define P_WIDTH 8
#define P_HEIGHT 8
#endif
/* SPEED should NOT be 8 or bigger: it may cause bugs when handling
* collisions! */
#define SPEED PXSIZE*2
#include <stdbool.h>
#include "config.h"
#include "game.h"
#include "memory.h"
@ -12,53 +25,27 @@
/* only methods propotypes are now in dedicated header files */
/* player_draw()
*
* Draws the player. This function should be called after drawing the
* map!
* game: The game struct which contains the player struct used.
*/
/* Draws the player player. This function should be called after drawing the
* map! */
void player_draw(Game *game);
/* player_move()
*
* Move the player in a direction.
* game: The game struct.
* direction: The direction to move the player in.
*/
/* Move the player player in the direction direction. */
void player_move(Game *game, Direction direction);
/* (Mibi88) TODO: Describe this function please, I've no idea what she's for! */
void player_action(Game *game);
/* player_collision()
*
* Check if the player is in collision with the map or a NPC. Checkpos is used
* to check the axis where the player is not moving.
* game: The game struct.
* direction: The direction the player is moving in.
* nomov_axis_check: The axis that isn't changed by this movement.
*/
/* Check if the player is in collision with the map or a NPC. Checkpos is used
* to check the axis where the player is not moving. */
bool player_collision(Game *game, Direction direction,
Checkpos nomov_axis_check);
/* player_fix_position()
*
* Fix the position of the player so that he's not a bit inside of a hard block
* after a collision.
* game: The game struct.
* fix_x: If we should fix the position on the X axis.
* fix_y: If we should fix the position on the Y axis.
*/
/* Fix the position of the player so that he's not a bit inside of a hard block
* after a collision. */
void player_fix_position(Game *game, bool fix_x, bool fix_y);
/* player_damage()
*
* Apply damage to player
* game: The game struct.
* amount: The amount of damage to apply.
*/
/* Apply damage to player */
void player_damage(Game *game, int amount);
#endif