Skip to content

Commit

Permalink
Changes from 405 project
Browse files Browse the repository at this point in the history
  • Loading branch information
EmperorPenguin18 committed Dec 8, 2023
1 parent 52a561e commit 331f7d8
Show file tree
Hide file tree
Showing 12 changed files with 303 additions and 19,074 deletions.
14 changes: 14 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -255,4 +255,18 @@ if(NOT stbttf_POPULATED)
target_include_directories(tidal2d PRIVATE "${stbttf_SOURCE_DIR}")
endif()

#zpl dependency
FetchContent_Declare(
zpl
URL https://github.com/zpl-c/zpl/releases/download/19.4.1/zpl.h
URL_MD5 2f59a58c27107a1c832a30f74c52168c
DOWNLOAD_NO_EXTRACT true
DOWNLOAD_NO_PROGRESS true
)
FetchContent_GetProperties(zpl)
if(NOT zpl_POPULATED)
FetchContent_Populate(zpl)
target_include_directories(tidal2d PRIVATE "${zpl_SOURCE_DIR}")
endif()

install(TARGETS tidal2d DESTINATION bin)
175 changes: 175 additions & 0 deletions ase.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
#include <stdlib.h>
#include <stdio.h>
#define STB_IMAGE_IMPLEMENTATION
#include <stb/stb_image.h>
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include <stb/stb_image_write.h>

struct ase_header {
uint32_t file_size;
uint16_t magic_number;
uint16_t frames;
uint16_t width;
uint16_t height;
uint16_t color_depth;
uint32_t flags;
uint16_t speed; //deprecated
uint32_t ignore_0;
uint32_t ignore_1;
uint8_t transparent_idx;
uint8_t ignore_2[3];
uint16_t num_colors;
uint8_t pixel_width;
uint8_t pixel_height;
int16_t x;
int16_t y;
uint16_t grid_width;
uint16_t grid_height;
uint8_t ignore_3[80];
};
typedef struct ase_header ase_header;

void ase_print_header(ase_header* header) {
printf("file_size: %d\n", header->file_size);
printf("magic_number: %#x\n", header->magic_number);
printf("frames: %d\n", header->frames);
printf("width: %d\n", header->width);
printf("height: %d\n", header->height);
printf("color_depth: %d\n", header->color_depth);
printf("flags: %#x\n", header->flags);
printf("speed: %d\n", header->speed);
printf("ignore_0: %d\n", header->ignore_0);
printf("ignore_1: %d\n", header->ignore_1);
printf("transparent_idx: %d\n", header->transparent_idx);
for (int n = 0; n < 3; n++) printf("ignore_2[%d]: %d\n", n, header->ignore_2[n]);
printf("num_colors: %d\n", header->num_colors);
printf("pixel_width: %d\n", header->pixel_width);
printf("pixel_height: %d\n", header->pixel_height);
printf("x: %d\n", header->x);
printf("y: %d\n", header->y);
printf("grid_width: %d\n", header->grid_width);
printf("grid_height: %d\n", header->grid_height);
for (int n = 0; n < 80; n++) printf("ignore_3[%d]: %d\n", n, header->ignore_3[n]);
}

struct ase_frame {
uint32_t size;
uint16_t magic_number;
uint16_t chunks_old;
uint16_t duration;
uint8_t ignore_0[2];
uint32_t chunks;
};
typedef struct ase_frame ase_frame;

void ase_print_frame(ase_frame* frame) {
printf("size: %d\n", frame->size);
printf("magic_number: %#x\n", frame->magic_number);
printf("chunks_old: %d\n", frame->chunks_old);
printf("duration: %d\n", frame->duration);
for (int n = 0; n < 2; n++) printf("ignore_0[%d]: %d\n", n, frame->ignore_0[n]);
printf("chunks: %d\n", frame->chunks);
}

struct ase_chunk {
uint32_t size;
uint16_t type;
uint8_t* data;
};
typedef struct ase_chunk ase_chunk;

int main(int argc, char** argv) {
ase_header header;
if (argc > 1) {
unsigned char* pixels = malloc(0);
size_t pixels_size = 0;
FILE* file = fopen(argv[1], "rb");
fread(&header, sizeof(header), 1, file);
int bpp = header.color_depth / 8;
assert(bpp == 1 || bpp == 2 || bpp == 4);
assert(header.magic_number == 0xA5E0);
assert(header.ignore_0 == 0);
assert(header.ignore_1 == 0);
for (int n = 0; n < 80; n++) assert(header.ignore_3[n] == 0);
for (uint16_t i = 0; i < header.frames; i++) {
ase_frame frame;
fread(&frame, sizeof(frame), 1, file);
assert(frame.magic_number == 0xF1FA);
assert(frame.chunks != 0);
for (int n = 0; n < 2; n++) assert(frame.ignore_0[n] == 0);
for (uint32_t j = 0; j < frame.chunks; j++) {
ase_chunk chunk;
fread(&chunk, sizeof(uint32_t)+sizeof(uint16_t), 1, file);
assert(chunk.size >= 6);
assert(chunk.type != 0);
chunk.data = malloc(chunk.size-6);
fread(chunk.data, chunk.size-6, 1, file);
switch (chunk.type) {
case 0x2007:
//Color Profile Chunk
break;
case 0x2019:
//Palette Chunk
break;
case 0x2004:
//Layer Chunk
break;
case 0x2005:
//Cel Chunk
uint16_t layer_idx = *(chunk.data+0);
int16_t x = *(chunk.data+2);
int16_t y = *(chunk.data+4);
uint8_t opacity = *(chunk.data+6);
uint16_t cel_type = *(chunk.data+7);
int16_t z_idx = *(chunk.data+9);
switch (cel_type) {
case 0: {
//Raw Image Data
pixels = realloc(pixels, pixels_size+(header.width*header.height*bpp));
memcpy(pixels+pixels_size, chunk.data+20, header.width*header.height*bpp);
pixels_size += header.width*header.height*bpp;
break;
}
case 1: {
//Linked cel
break;
}
case 2: {
//Compressed Image
//TODO handle transparency
int uncompressed_size = 0;
char* uncompressed =
stbi_zlib_decode_malloc(chunk.data+20,
header.width*header.height*bpp, &uncompressed_size);
pixels = realloc(pixels, pixels_size+uncompressed_size);
memcpy(pixels+pixels_size, uncompressed, uncompressed_size);
free(uncompressed);
pixels_size += uncompressed_size;
break;
}
case 3: {
//Compressed Tilemap
break;
}
default: {
//Error
exit(1);
break;
}
}
break;
default:
//Ignore others
break;
}
free(chunk.data);
}
}
assert(ftell(file) == header.file_size);
fclose(file);
assert(pixels_size == header.width*header.height*header.frames*bpp);
stbi_write_png("test.png", header.width, header.height*header.frames, bpp, pixels, 0);
free(pixels);
}
return 0;
};
83 changes: 71 additions & 12 deletions src/actions.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//https://github.com/EmperorPenguin18/tidal2d/blob/main/LICENSE

#include <string.h>
#include <unistd.h>

#include "actions.h"

Expand Down Expand Up @@ -30,12 +31,21 @@ static void action_move(Engine* e, Instance* instance, char* args) {
float x = *(float*)args;
float y = *(float*)(args+sizeof(float));
bool relative = *(bool*)(args+(2*sizeof(float)));
if (!instance->body) return;
if (relative) {
cpVect v = cpBodyGetPosition(instance->body);
cpVect rel = cpvadd(v, cpv(x, y));
cpBodySetPosition(instance->body, rel);
} else cpBodySetPosition(instance->body, cpv(x, y));
if (instance->body) {
if (relative) {
cpVect v = cpBodyGetPosition(instance->body);
cpVect rel = cpvadd(v, cpv(x, y));
cpBodySetPosition(instance->body, rel);
} else cpBodySetPosition(instance->body, cpv(x, y));
} else {
if (relative) {
instance->dst.x += x;
instance->dst.y += y;
} else {
instance->dst.x = x;
instance->dst.y = y;
}
}
}

/* Change a physics body velocity. See action documentation. */
Expand Down Expand Up @@ -257,6 +267,12 @@ static void action_text(Engine* e, Instance* instance, char* args) {
instance->text = string;
}

/* Set hidden. See action documentation. */
static void action_hide(Engine* e, Instance* instance, char* args) {
bool state = *args;
instance->hidden = state;
}

/* Fill in memory with specified structure.
* Variadic arguments must be in pairs of two.
* STRING is string, INTEGER is number, and REAL is bool.
Expand Down Expand Up @@ -486,6 +502,13 @@ static int action_handler(Action* action, zpl_json_object* json, Asset* assets,
action->free = 0;
action->run = &action_text;

} else if (strcmp(type, "hide") == 0) {
action->args =
args_generator(json, 1, "state", ZPL_ADT_TYPE_REAL);
if (action->args == NULL) return ERROR("Args generator failed: %s", type);
action->free = 1;
action->run = &action_hide;

} else return ERROR("Invalid action type found: %s", type);
free(type);
return 0;
Expand All @@ -508,16 +531,25 @@ void action_cleanup(Action* action) {
*/
int action_api(lua_State *L) {
Engine* e = lua_touserdata(L, 1);
if (e == NULL) return 0;
if (e == NULL) {
ERROR("Engine is nil");
return 0;
}
Instance* instance = lua_touserdata(L, 2);
if (instance == NULL) return 0;
if (instance == NULL) {
ERROR("Instance is nil");
return 0;
}
const char* string = luaL_checkstring(L, 3);
char* str = malloc(strlen(string)+1);
strcpy(str, string);
Action action;
zpl_json_object json;
zpl_json_parse(&json, str, zpl_heap());
if (action_init(&action, &json, e->assets, e->assets_num) < 0) return 0; //should improve error handling later
if (action_init(&action, &json, e->assets, e->assets_num) < 0) {
exit(1);
//return 0; //should improve error handling later
}
free(str);
zpl_json_free(&json);
action.run(e, instance, action.args);
Expand All @@ -528,9 +560,15 @@ int action_api(lua_State *L) {
/* Unique spawn function because we want to return the new instance. */
int spawn_api(lua_State *L) {
Engine* e = lua_touserdata(L, 1);
if (e == NULL) return 0;
if (e == NULL) {
ERROR("Engine is nil");
return 0;
}
Instance* instance = lua_touserdata(L, 2);
if (instance == NULL) return 0;
if (instance == NULL) {
ERROR("Instance is nil");
return 0;
}
const char* object = luaL_checkstring(L, 3);
float x = luaL_checknumber(L, 4);
float y = luaL_checknumber(L, 5);
Expand All @@ -540,7 +578,8 @@ int spawn_api(lua_State *L) {
x += v.x;
y += v.y;
}
lua_pushlightuserdata(L, instance_copy(e, object, x, y));
Instance* new_instance = instance_copy(e, object, x, y);
lua_pushlightuserdata(L, new_instance);
return 1;
}

Expand All @@ -549,3 +588,23 @@ int register_action(lua_State *L) {
SDL_Log("Not implemented");
return 0;
}

/* */
int measure_api(lua_State *L) {
Instance* instance = lua_touserdata(L, 1);
if (instance == NULL) {
ERROR("Instance is nil");
return 0;
}
const char* str = luaL_checkstring(L, 2);
lua_pushnumber(L, STBTTF_MeasureText(instance->font, str));
return 1;
}

/* */
int sleep_api(lua_State *L) {
double time = luaL_checknumber(L, 1);
sleep(time);
return 0;
}

3 changes: 2 additions & 1 deletion src/assets.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
#ifndef __ASSETS_H__
#define __ASSETS_H__

#include "zpl.h"
#include <zpl.h>

#include "common.h"

/* Asset definition. Name is the file name
Expand Down
Loading

0 comments on commit 331f7d8

Please sign in to comment.