resor.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. /*
  2. * Resor: wrapper for loadable resources such as bitmaps, fonts, music,
  3. * etc.
  4. * The main intent is to wrap this on the scripting side.
  5. *
  6. */
  7. #include "eruta.h"
  8. #include "resor.h"
  9. #include "mem.h"
  10. #include "fifi.h"
  11. #include "bad.h"
  12. #include <rebox.h>
  13. #include <assert.h>
  14. /* typedef int ResorDestructor(Resor * self); */
  15. struct Resor_ {
  16. ResorKind kind;
  17. ResorData data;
  18. ResorStatus status;
  19. ResorDestructor * free;
  20. };
  21. static int resor_free_font(Resor * self) {
  22. ALLEGRO_FONT * data;
  23. if (!self) return RESOR_NULL;
  24. assert(self->kind == RESOR_FONT);
  25. data = self->data.font;
  26. if (!data) return RESOR_EMPTY;
  27. al_destroy_font(data);
  28. self->data.font = NULL;
  29. return RESOR_OK;
  30. }
  31. static int resor_free_bitmap(Resor * self) {
  32. ALLEGRO_BITMAP * data;
  33. if (!self) return RESOR_NULL;
  34. assert(self->kind == RESOR_BITMAP);
  35. data = self->data.bitmap;
  36. if (!data) return RESOR_EMPTY;
  37. al_destroy_bitmap(data);
  38. self->data.bitmap = NULL;
  39. return RESOR_OK;
  40. }
  41. static int resor_free_sample(Resor * self) {
  42. ALLEGRO_SAMPLE * data;
  43. if (!self) return RESOR_NULL;
  44. assert(self->kind == RESOR_SAMPLE);
  45. data = self->data.sample;
  46. if (!data) return RESOR_EMPTY;
  47. al_destroy_sample(data);
  48. self->data.sample = NULL;
  49. return RESOR_OK;
  50. }
  51. static int resor_free_audio_stream(Resor * self) {
  52. ALLEGRO_AUDIO_STREAM * data;
  53. if (!self) return RESOR_NULL;
  54. assert(self->kind == RESOR_AUDIO_STREAM);
  55. data = self->data.stream;
  56. if (!data) return RESOR_EMPTY;
  57. al_destroy_audio_stream(data);
  58. self->data.stream = NULL;
  59. return RESOR_OK;
  60. }
  61. /* Cleans up the contents of the resource. */
  62. int resor_done(Resor * self) {
  63. int res;
  64. if(!self) return RESOR_NULL;
  65. if(self->free) {
  66. res = self->free(self);
  67. self->kind = RESOR_NONE;
  68. return res;
  69. }
  70. return RESOR_OK;
  71. }
  72. /* Cleans up the contents of the resource and deallocates the memory self points to. */
  73. int resor_free(Resor * self) {
  74. int res = resor_done(self);
  75. mem_free(self);
  76. return res;
  77. }
  78. /* Returns the resource kind. */
  79. int resor_kind(Resor * self) {
  80. if (!self) return RESOR_EMPTY;
  81. return self->kind;
  82. }
  83. /* Generic initialization for resor */
  84. Resor * resor_init(Resor * self, ResorKind kind, ResorData data, ResorDestructor * free) {
  85. if(!self) return NULL;
  86. self->kind = kind;
  87. self->data = data;
  88. self->free = free;
  89. self->status = RESOR_OK;
  90. return self;
  91. }
  92. /* Allocate a resor struct */
  93. Resor * resor_alloc() {
  94. return STRUCT_ALLOC(Resor);
  95. }
  96. /* Allocate and initialize a resor struct. */
  97. Resor * resor_new(ResorKind kind, ResorData data, ResorDestructor * free) {
  98. Resor * self;
  99. self = resor_alloc();
  100. return resor_init(self, kind, data, free);
  101. }
  102. /* Allocate and initialize a resor struct for use with fonts. */
  103. Resor * resor_new_font(ALLEGRO_FONT * font) {
  104. ResorData data;
  105. if(!font) return NULL;
  106. data.font = font;
  107. return resor_new(RESOR_FONT, data, resor_free_font);
  108. }
  109. /* Allocate and initialize a resor struct for use with bitmaps. */
  110. Resor * resor_new_bitmap(ALLEGRO_BITMAP * bitmap) {
  111. ResorData data;
  112. if(!bitmap) return NULL;
  113. data.bitmap = bitmap;
  114. return resor_new(RESOR_BITMAP, data, resor_free_bitmap);
  115. }
  116. /* Allocate and initialize a resor struct for use with samples. */
  117. Resor * resor_new_sample(ALLEGRO_SAMPLE * sample) {
  118. ResorData data;
  119. if (!sample) return NULL;
  120. data.sample = sample;
  121. return resor_new(RESOR_SAMPLE, data, resor_free_sample);
  122. }
  123. /* Allocate and initialize a resor struct for use with fonts. */
  124. Resor * resor_new_audio_stream(ALLEGRO_AUDIO_STREAM * stream) {
  125. ResorData data;
  126. if(!stream) return NULL;
  127. data.stream = stream;
  128. return resor_new(RESOR_AUDIO_STREAM, data, resor_free_audio_stream);
  129. }
  130. /* Allocate and initialize a resor struct for use with other data . */
  131. Resor * resor_new_other(ResorKind kind, void * data, ResorDestructor * free) {
  132. Resor * self;
  133. ResorData rdata;
  134. rdata.other = data;
  135. self = resor_alloc();
  136. return resor_init(self, kind, rdata, free);
  137. }
  138. /*
  139. * Loads a TTF font from the data directory as a resource.
  140. */
  141. Resor * resor_load_ttf_font_stretch(const char * vpath, int w, int h, int flags) {
  142. return resor_new_font(fifi_load_ttf_font_stretch(vpath, w, h, flags));
  143. }
  144. /**
  145. * Loads a TTF font from the data directory as a resource.
  146. */
  147. Resor * resor_load_ttf_font(const char * vpath, int h, int flags) {
  148. return resor_new_font(fifi_load_ttf_font(vpath, h, flags));
  149. }
  150. /*
  151. * Loads a bitmap font from the data directory as a resource
  152. */
  153. Resor * resor_load_bitmap_font_flags(const char * vpath, int flags) {
  154. return resor_new_font(fifi_load_bitmap_font_flags(vpath, flags));
  155. }
  156. /*
  157. * Loads a bitmap font from the data directory as a resource.
  158. */
  159. Resor * resor_load_bitmap_font(const char * vpath) {
  160. return resor_new_font(fifi_load_bitmap_font(vpath));
  161. }
  162. /*
  163. * Loads an audio stream from the data directory as a resource
  164. */
  165. Resor *
  166. resor_load_audio_stream(const char * vpath, size_t buffer_count, int samples) {
  167. return resor_new_audio_stream(fifi_load_audio_stream(vpath, buffer_count, samples));
  168. }
  169. /*
  170. * Loads a sample from the data directory as a resource.
  171. */
  172. Resor * resor_load_sample(const char * vpath) {
  173. return resor_new_sample(fifi_load_sample(vpath));
  174. }
  175. /*
  176. * Loads a bitmap from the data directory as a resource.
  177. */
  178. Resor * resor_load_bitmap_flags(const char * vpath, int flags) {
  179. return resor_new_bitmap(fifi_load_bitmap_flags(vpath, flags));
  180. }
  181. /*
  182. * Loads a bitmap from the data directory as a resource.
  183. */
  184. Resor * resor_load_bitmap(const char * vpath) {
  185. return resor_new_bitmap(fifi_load_bitmap(vpath));
  186. }
  187. /* Loads an other resource using the loader callback */
  188. Resor *
  189. resor_load_other(const char *vpath, ResorKind kind,
  190. ResorLoader * loader, ResorDestructor * destroy, void *extra) {
  191. void * data = loader(vpath, extra);
  192. if (!data) return NULL;
  193. return resor_new_other(kind, data, destroy);
  194. }
  195. /* Grabs a font from an ALLEGRO_BITMAP and puts it in a resor */
  196. Resor *
  197. resor_grab_font_from_bitmap(ALLEGRO_BITMAP * bmp, int count, int ranges[]) {
  198. return resor_new_font(al_grab_font_from_bitmap(bmp, count, ranges));
  199. }
  200. /* Grabs a font from an Resor that must contain a bitmap and puts it in a resor */
  201. Resor *
  202. resor_grab_font_from_resor(Resor * res, int count, int ranges[]) {
  203. ALLEGRO_BITMAP * bmp;
  204. bmp = resor_bitmap(res);
  205. if (!bmp) return NULL;
  206. return resor_grab_font_from_bitmap(bmp, count, ranges);
  207. }
  208. /* Gets the font stored in the resource.
  209. * Returns NULL if not a font or not a valid resource.
  210. */
  211. ALLEGRO_FONT * resor_font(Resor * self) {
  212. if(!self) return NULL;
  213. if(self->kind != RESOR_FONT) return NULL;
  214. return self->data.font;
  215. }
  216. /* Gets the bitmap stored in the resource.
  217. * Returns NULL if not a font or not a valid resource.
  218. */
  219. ALLEGRO_BITMAP * resor_bitmap(Resor * self) {
  220. if(!self) return NULL;
  221. if(self->kind != RESOR_BITMAP) return NULL;
  222. return self->data.bitmap;
  223. }
  224. /* Gets the audio stream stored in the resource.
  225. * Returns NULL if not a font or not a valid resource.
  226. */
  227. ALLEGRO_AUDIO_STREAM * resor_audio_stream(Resor * self) {
  228. if(!self) return NULL;
  229. if(self->kind != RESOR_AUDIO_STREAM) return NULL;
  230. return self->data.stream;
  231. }
  232. /* Gets the sample stored in the resource.
  233. * Returns NULL if not a font or not a valid resource.
  234. */
  235. ALLEGRO_SAMPLE * resor_sample(Resor * self) {
  236. if(!self) return NULL;
  237. if(self->kind != RESOR_SAMPLE) return NULL;
  238. return self->data.sample;
  239. }
  240. /** Gets the other data stored in resor, but checks the type. If type not correct returns NULL too. */
  241. void * resor_other(Resor * self, unsigned kind) {
  242. if(!self) return NULL;
  243. if(self->kind != kind) return NULL;
  244. return self->data.other;
  245. }
  246. /* If the resource is a font, stores the ascent of the font into value
  247. * and returns true . Otherwise, returns false
  248. */
  249. bool resor_get_font_ascent(Resor * self, int * value) {
  250. ALLEGRO_FONT * font= resor_font(self);
  251. if (!font) return false;
  252. if (!value) return false;
  253. (*value) = al_get_font_ascent(font);
  254. return true;
  255. }
  256. /* If the resource is a font, stores the descent of the font into value
  257. * and returns true . Otherwise, returns false
  258. */
  259. bool resor_get_font_descent(Resor * self, int * value) {
  260. ALLEGRO_FONT * font= resor_font(self);
  261. if (!font) return false;
  262. if (!value) return false;
  263. (*value) = al_get_font_descent(font);
  264. return true;
  265. }
  266. /* If the resource is a font, stores the line height of the font into value
  267. * and returns true . Otherwise, returns false
  268. */
  269. bool resor_get_font_line_height(Resor * self, int * value) {
  270. ALLEGRO_FONT * font = resor_font(self);
  271. if (!font) return false;
  272. if (!value) return false;
  273. (*value) = al_get_font_line_height(font);
  274. return true;
  275. }
  276. /* If the resource is a font, stores the width of the given text in the font into
  277. * value and returns true . Otherwise, returns false
  278. */
  279. bool resor_get_text_width(Resor * self, char * text, int * value) {
  280. ALLEGRO_FONT * font = resor_font(self);
  281. if (!font) return false;
  282. if (!value) return false;
  283. (*value) = al_get_text_width(font, text);
  284. return true;
  285. }
  286. /* If the resource is a font, stores the dimensions of the given text in the
  287. * font into value and returns true. Otherwise, returns false
  288. */
  289. bool resor_get_text_dimensions(Resor * self, char * text, Rebox * value) {
  290. int bbx = 0, bby = 0, bbw = 0, bbh = 0;
  291. ALLEGRO_FONT * font = resor_font(self);
  292. if (!font) return false;
  293. if (!value) return false;
  294. al_get_text_dimensions(font, text, &bbx, &bby, &bbw, &bbh);
  295. value->at.x = bbx;
  296. value->at.y = bby;
  297. value->size.x = bbw;
  298. value->size.y = bbh;
  299. return true;
  300. }
  301. /* If the resource is a font, stores the width of the given text in the font into
  302. * value and returns true . Otherwise, returns false
  303. */
  304. bool resor_get_ustr_width(Resor * self, ALLEGRO_USTR * text, int * value) {
  305. ALLEGRO_FONT * font = resor_font(self);
  306. if (!font) return false;
  307. if (!value) return false;
  308. (*value) = al_get_ustr_width(font, text);
  309. return true;
  310. }
  311. /* If the resource is a font, stores the dimensions of the given text in the
  312. * font into value and returns true. Otherwise, returns false
  313. */
  314. bool resor_get_ustr_dimensions(Resor * self, ALLEGRO_USTR * text, Rebox * value) {
  315. int bbx = 0, bby = 0, bbw = 0, bbh = 0;
  316. ALLEGRO_FONT * font = resor_font(self);
  317. if (!font) return false;
  318. if (!value) return false;
  319. al_get_ustr_dimensions(font, text, &bbx, &bby, &bbw, &bbh);
  320. value->at.x = bbx;
  321. value->at.y = bby;
  322. value->size.x = bbw;
  323. value->size.y = bbh;
  324. return true;
  325. }
  326. /* If the resource is a bitmap, stores the width of the bitmap into
  327. * value and returns true . Otherwise, returns false
  328. */
  329. bool resor_get_bitmap_width(Resor * self, int * value) {
  330. ALLEGRO_BITMAP * bmp = resor_bitmap(self);
  331. if (!bmp) return false;
  332. if (!value) return false;
  333. (*value) = al_get_bitmap_width(bmp);
  334. return true;
  335. }
  336. /* If the resource is a bitmap, stores the height of the bitmap into
  337. * value and returns true . Otherwise, returns false
  338. */
  339. bool resor_get_bitmap_height(Resor * self, int * value) {
  340. ALLEGRO_BITMAP * bmp = resor_bitmap(self);
  341. if (!bmp) return false;
  342. if (!value) return false;
  343. (*value) = al_get_bitmap_height(bmp);
  344. return true;
  345. }
  346. /* If the resource is a bitmap, stores the flags of the bitmap into
  347. * value and returns true . Otherwise, returns false
  348. */
  349. bool resor_get_bitmap_flags(Resor * self, int * value) {
  350. ALLEGRO_BITMAP * bmp = resor_bitmap(self);
  351. if (!bmp) return false;
  352. if (!value) return false;
  353. (*value) = al_get_bitmap_flags(bmp);
  354. return true;
  355. }
  356. /* If the resource is a bitmap, stores the format of the bitmap into
  357. * value and returns true . Otherwise, returns false
  358. */
  359. bool resor_get_bitmap_format(Resor * self, int * value) {
  360. ALLEGRO_BITMAP * bmp = resor_bitmap(self);
  361. if (!bmp) return false;
  362. if (!value) return false;
  363. (*value) = al_get_bitmap_format(bmp);
  364. return true;
  365. }