1 /*! \file
2  * \brief Match record file handling.
3  * \details Functions and structs for reading, writing and modifying OMF:2097 match record (REC) files.
4  * \copyright MIT license.
5  * \date 2013-2014
6  * \author Andrew Thompson
7  * \author Tuomas Virtanen
8  */
9 
10 #ifndef _SD_REC_H
11 #define _SD_REC_H
12 
13 #include <stdint.h>
14 #include <stddef.h>
15 #include "shadowdive/pilot.h"
16 #include "shadowdive/palette.h"
17 #include "shadowdive/sprite.h"
18 #include "shadowdive/actions.h"
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23 
24 /*! \brief REC action record
25  *
26  * AA record of a single action during the match.
27  * Essentially a record of keys pressed at a given tick.
28  */
29 typedef struct {
30     uint32_t tick;      ///< Game tick at the moment of this event
31     uint8_t lookup_id;  ///< Extra content id. Valid values 2,3,5,6,10,18.
32     uint8_t player_id;  ///< Player ID. 0 or 1.
33     sd_action action;   ///< Player actions at this tick. A Combination of sd_rec_action enums.
34     uint8_t raw_action; ///< Raw action data from the file.
35     char *extra_data;   ///< Extra data. Check length using sd_rec_extra_len(). NULL if does not exist.
36 } sd_rec_move;
37 
38 /*! \brief REC pilot container
39  *
40  * Information about a single pilot in the match.
41  * \todo Find out about the unknowns here
42  */
43 typedef struct {
44     sd_pilot info;       ///< Pilot information
45     uint8_t unknown_a;   ///< Unknown value \todo: Find this out
46     uint16_t unknown_b;  ///< Unknown value \todo: Find this out
47     sd_palette pal;      ///< Palette for this pilot photo
48     uint8_t has_photo;   ///< Tells if the pilot has a photo sprite
49     sd_sprite photo;     ///< Photo sprite
50 } sd_rec_pilot;
51 
52 /*! \brief REC recording
53  *
54  * Contains a record of a single OMF:2097 match. This may be
55  * a network match, tournament match, singleplayer match ...
56  * The data varies slightly depending on the type.
57  * \todo Find out about the unknowns. Possibly hyper mode, etc.
58  */
59 typedef struct {
60     sd_rec_pilot pilots[2]; ///< Information about the pilots
61     uint32_t scores[2];     ///< Score data at the start of the match
62     int8_t unknown_a;       ///< Is Fire or ice ? 0 = no, 1 = fire, 2 = ice ?
63     int8_t unknown_b;       ///< Unknown \todo: Find out
64     int8_t unknown_c;       ///< Unknown \todo: Find out
65 
66     int16_t throw_range;    ///< Throw range (%)
67     int16_t hit_pause;      ///< Hit pause (ticks)
68     int16_t block_damage;   ///< Block damage (%)
69     int16_t vitality;       ///< Vitality (%)
70     int16_t jump_height;    ///< Jump height (%)
71     int16_t unknown_i;      ///< Unknown \todo: Find out
72     int16_t unknown_j;      ///< Unknown \todo: Find out
73     int16_t unknown_k;      ///< Unknown \todo: Find out
74 
75     uint8_t knock_down;     ///< Knock down (0 = None, 1 = Kicks, 2 = Punches, 3 = both)
76     uint8_t rehit_mode;     ///< Rehit mode (On/Off)
77     uint8_t def_throws;     ///< Def. Throws (On/Off)
78     uint8_t arena_id;       ///< Arena ID
79     uint8_t power[2];       ///< Power 1,2 (0-7?)
80     uint8_t hazards;        ///< Hazards (On/Off)
81     uint8_t round_type;     ///< Round type (0=1, 1=2/3, 2=3/5, 3=4/7)
82     uint8_t unknown_l;      ///< Currently unknown \todo Find out what this does
83     uint8_t hyper_mode;     ///< Hyper mode (On/Off)
84 
85     int8_t unknown_m;       ///< Unknown \todo: Find out
86 
87     unsigned int move_count; ///< How many REC event records
88     sd_rec_move *moves; ///< REC event records list
89 } sd_rec_file;
90 
91 /*! \brief Initialize REC file structure
92  *
93  * Initializes the REC file structure with empty values.
94  *
95  * \retval SD_INVALID_INPUT REC struct pointer was NULL
96  * \retval SD_SUCCESS Success.
97  *
98  * \param rec Allocated REC struct pointer.
99  */
100 int sd_rec_create(sd_rec_file *rec);
101 
102 /*! \brief Free REC file structure
103  *
104  * Frees up all memory reserved by the REC structure.
105  * All contents will be freed, all pointers to contents will be invalid.
106  *
107  * \param rec REC file struct pointer.
108  */
109 void sd_rec_free(sd_rec_file *rec);
110 
111 /*! \brief Load .REC file
112  *
113  * Loads the given REC file to memory. The structure must be initialized with sd_rec_create()
114  * before using this function. Loading to a previously loaded or filled sd_rec_file structure
115  * will result in old data and pointers getting lost. This is very likely to cause a memory leak.
116  *
117  * \retval SD_FILE_OPEN_ERROR File could not be opened.
118  * \retval SD_FILE_PARSE_ERROR File does not contain valid data or has syntax problems.
119  * \retval SD_OUT_OF_MEMORY Memory ran out. This struct should now be considered invalid and freed.
120  * \retval SD_SUCCESS Success.
121  *
122  * \param rec BK struct pointer.
123  * \param filename Name of the BK file to load from.
124  */
125 int sd_rec_load(sd_rec_file *rec, const char *filename);
126 
127 /*! \brief Save .REC file
128  *
129  * Saves the given REC file from memory to a file on disk. The structure must be at
130  * least initialized by using sd_rec_create() before running this.
131  *
132  * \retval SD_FILE_OPEN_ERROR File could not be opened for writing.
133  * \retval SD_SUCCESS Success.
134  *
135  * \param rec REC struct pointer.
136  * \param filename Name of the REC file to save into.
137  */
138 int sd_rec_save(sd_rec_file *rec, const char *filename);
139 
140 /*! \brief Deletes a REC event record
141  *
142  * Deletes a REC event record at given position.
143  *
144  * \retval SD_OUT_OF_MEMORY Memory ran out. The REC structure will most likely be invalid.
145  * \retval SD_INVALID_INPUT Number you tried to remove does not exist, or rec was NULL.
146  * \retval SD_SUCCESS Success.
147  *
148  * \param rec BK struct pointer.
149  * \param number Record number
150  */
151 int sd_rec_delete_action(sd_rec_file *rec, unsigned int number);
152 
153 int sd_rec_extra_len(int key);
154 
155 /*! \brief Inserts a REC event record
156  *
157  * Inserts a new event record to a given position. All contents starting from the given
158  * position will be moved forwards by one entry.
159  *
160  * You can push new entries to the end of the list by pointing to the last+1 entry.
161  *
162  * Event record data will be copied. Make sure to free your local copy yourself.
163  *
164  * \retval SD_OUT_OF_MEMORY Memory ran out. The REC structure will most likely be invalid.
165  * \retval SD_INVALID_INPUT Slot you tried to insert to does not exist, or rec was NULL.
166  * \retval SD_SUCCESS Success.
167  *
168  * \param rec BK struct pointer.
169  * \param number Record number
170  * \param move Move to insert
171  */
172 int sd_rec_insert_action(sd_rec_file *rec, unsigned int number, const sd_rec_move *move);
173 
174 #ifdef __cplusplus
175 }
176 #endif
177 
178 #endif // _SD_REC_H
179