Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,6 @@ else()

if (NINTENDO_3DS)
set(ROMFS_DIR "${CMAKE_CURRENT_BINARY_DIR}/romfs")
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/export/data DESTINATION ${ROMFS_DIR})
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/export/carts DESTINATION ${ROMFS_DIR})
set(SMDH_FILE "${CMAKE_CURRENT_BINARY_DIR}/${APP_NAME}.smdh")
ctr_generate_smdh("${SMDH_FILE}"
Expand Down
1 change: 0 additions & 1 deletion cmake/project_config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ set(project_sources
${CMAKE_CURRENT_SOURCE_DIR}/src/app.c
${CMAKE_CURRENT_SOURCE_DIR}/src/auxiliary.c
${CMAKE_CURRENT_SOURCE_DIR}/src/core.c
${CMAKE_CURRENT_SOURCE_DIR}/src/image_loader.c
${CMAKE_CURRENT_SOURCE_DIR}/src/memory.c
${CMAKE_CURRENT_SOURCE_DIR}/src/p8scii.c
${CMAKE_CURRENT_SOURCE_DIR}/src/lexaloffle/p8_compress.c
Expand Down
Binary file removed export/data/frame.png
Binary file not shown.
1 change: 0 additions & 1 deletion res/open8.pkg
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
"..\out\build\N-Gage\open8.app"-"E:\System\Apps\open8\open8.app"
"..\out\build\N-Gage\open8.rsc"-"E:\System\Apps\open8\open8.rsc"
"..\out\build\N-Gage\open8.aif"-"E:\System\Apps\open8\open8.aif"
"..\export\data\frame.png"-"E:\System\Apps\open8\data\frame.png"
"..\export\carts\automata.p8.png"-"E:\System\Apps\open8\carts\automata.p8.png"
"..\export\carts\api.p8.png"-"E:\System\Apps\open8\carts\api.p8.png"
"..\export\carts\demo.p8.png"-"E:\System\Apps\open8\carts\demo.p8.png"
Expand Down
26 changes: 13 additions & 13 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,35 +12,35 @@

#include "SDL3/SDL.h"

#define SCREEN_SIZE 128

#ifdef __SYMBIAN32__
#define SCALE 1
#define WINDOW_W 176
#define WINDOW_H 208
#define WINDOW_FLAGS 0
#define FRAME_OFFSET_X 0
#define FRAME_OFFSET_Y 0
#define SCREEN_OFFSET_X 24
#define SCREEN_OFFSET_Y 25
#define FRAME_OFFSET_X 8
#define FRAME_OFFSET_Y 1
#elif defined __3DS__
#define SCALE 1
#define WINDOW_W 400
#define WINDOW_H 240
#define WINDOW_FLAGS 0
#define FRAME_OFFSET_X 112
#define FRAME_OFFSET_Y 16
#define SCREEN_OFFSET_X FRAME_OFFSET_X + 24
#define SCREEN_OFFSET_Y FRAME_OFFSET_Y + 25
#define FRAME_OFFSET_X 120
#define FRAME_OFFSET_Y 17
#else
#define SCALE 3
#define WINDOW_W 176
#define WINDOW_H 208
#define WINDOW_FLAGS (SDL_WINDOW_UTILITY)
#define FRAME_OFFSET_X 0
#define FRAME_OFFSET_Y 0
#define SCREEN_OFFSET_X 24
#define SCREEN_OFFSET_Y 25
#define FRAME_OFFSET_X 8
#define FRAME_OFFSET_Y 1
#endif

#define FRAME_W 160
#define FRAME_H 205

#define SCREEN_OFFSET_X FRAME_OFFSET_X + 16
#define SCREEN_OFFSET_Y FRAME_OFFSET_Y + 24
#define SCREEN_SIZE 128

#endif // CONFIG_H
121 changes: 50 additions & 71 deletions src/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@
#include "api.h"
#include "config.h"
#include "core.h"
#include "image_loader.h"
#include "memory.h"

#define STBI_ONLY_PNG
#define STBI_NO_THREAD_LOCALS
#define STB_IMAGE_IMPLEMENTATION
#include "misc/stb_image.h"

#ifdef _WIN32
Expand All @@ -27,8 +30,6 @@
#endif
#include <string.h>

static SDL_Texture* frame;

static char** available_carts;
static int num_carts;

Expand Down Expand Up @@ -83,13 +84,13 @@ static void destroy_vm(void)
lua_close(vm);
}

static void extract_pico8_data(const uint8_t* image_data, uint8_t* cart_data)
static void extract_pico8_data(uint8_t* image_data, uint8_t* cart_data)
{
size_t data_index = 0;
size_t pixel_count = CART_WIDTH * CART_HEIGHT;

// Each Pico-8 byte is stored as the two least significant bits of each of the four
// channels, ordered ABGR (E.g: the A channel stores the 2 most significant bits in
// channels, ordered ARGB (E.g: the A channel stores the 2 most significant bits in
// the bytes). The image is 160 pixels wide and 205 pixels high, for a possible
// storage of 32,800 (0x8020) bytes.

Expand All @@ -100,17 +101,20 @@ static void extract_pico8_data(const uint8_t* image_data, uint8_t* cart_data)
break;
}

// ABGR8888
uint8_t A = image_data[i * 4]; // A channel
uint8_t B = image_data[i * 4 + 1]; // B channel
uint8_t G = image_data[i * 4 + 2]; // G channel
uint8_t R = image_data[i * 4 + 3]; // R channel
// stb_image stores components in RGBA32 order
uint8_t R = image_data[i * 4]; // R channel
uint8_t G = image_data[i * 4 + 1]; // G channel
uint8_t B = image_data[i * 4 + 2]; // B channel
uint8_t A = image_data[i * 4 + 3]; // A channel

// Extract the 2 least significant bits from each channel.
uint8_t byte = ((B & 0x03) << 6) | ((G & 0x03) << 4) | ((R & 0x03) << 2) | (A & 0x03);
uint8_t byte = ((A & 0x03) << 6) | ((R & 0x03) << 4) | ((G & 0x03) << 2) | ((B & 0x03) << 0);

// Swap nibbles.
byte = (byte >> 4) | (byte << 4);
// Clean up graphical artifacts visible on 32bpp displays
image_data[i * 4] = (R & 0xFC) | (R >> 6);
image_data[i * 4 + 1] = (G & 0xFC) | (G >> 6);
image_data[i * 4 + 2] = (B & 0xFC) | (B >> 6);
image_data[i * 4 + 3] = (A & 0xFC) | (A >> 6);

cart_data[data_index] = byte;
data_index++;
Expand Down Expand Up @@ -189,39 +193,58 @@ static int load_cart(SDL_Renderer* renderer, const char* file_name, cart_t* cart
long file_size = ftell(file);
fseek(file, 0, SEEK_SET);

cart->data = (uint8_t*)SDL_calloc(file_size, sizeof(uint8_t));
if (!cart->data)
uint8_t* data = (uint8_t*)SDL_calloc(file_size, sizeof(uint8_t));
if (!data)
{
SDL_Log("Couldn't allocate memory for cart data");
fclose(file);
return 0;
}
fread(cart->data, 1, file_size, file);
cart->size = file_size;
fread(data, 1, file_size, file);
fclose(file);

uint32_t* image_data = (uint32_t*)stbi_load_from_memory(cart->data, cart->size, &width, &height, &bpp, 4);
uint8_t* image_data = stbi_load_from_memory(data, file_size, &width, &height, &bpp, 4);
if (!image_data)
{
SDL_Log("Couldn't load image data: %s", stbi_failure_reason());
SDL_free(data);
return 0;
}
SDL_free(data);

if (width != CART_WIDTH || height != CART_HEIGHT)
{
SDL_Log("Invalid image size: %dx%d", width, height);
stbi_image_free(image_data);
return 0;
}

SDL_Surface* surface = SDL_CreateSurfaceFrom(width, height, SDL_PIXELFORMAT_ABGR8888, image_data, width * 4);
extract_pico8_data(image_data, cart->cart_data);

SDL_Surface* surface = SDL_CreateSurfaceFrom(width, height, SDL_PIXELFORMAT_RGBA32, image_data, width * 4);
if (!surface)
{
SDL_Log("Couldn't create surface: %s", SDL_GetError());
stbi_image_free(image_data);
return 0;
}

extract_pico8_data((const uint8_t*)image_data, cart->cart_data);
cart->image = SDL_CreateTextureFromSurface(renderer, surface);
if (!cart->image)
{
SDL_Log("Couldn't create texture: %s", SDL_GetError());
SDL_DestroySurface(surface);
stbi_image_free(image_data);
return 0;
}

SDL_DestroySurface(surface);
stbi_image_free(image_data);

if (!SDL_SetTextureScaleMode(cart->image, SDL_SCALEMODE_NEAREST))
{
SDL_Log("Couldn't set texture scale mode: %s", SDL_GetError());
}

uint32_t header = *(uint32_t*)&cart->cart_data[0x4300];
int status = 0;
Expand All @@ -230,7 +253,7 @@ static int load_cart(SDL_Renderer* renderer, const char* file_name, cart_t* cart
if (!cart->code)
{
SDL_Log("Could not allocate code memory: %s", SDL_GetError());
stbi_image_free(image_data);
SDL_DestroyTexture(cart->image);
return 0;
}

Expand Down Expand Up @@ -266,7 +289,7 @@ static int load_cart(SDL_Renderer* renderer, const char* file_name, cart_t* cart
if (!cart->code)
{
SDL_Log("Could not re-allocate code memory: %s", SDL_GetError());
stbi_image_free(image_data);
SDL_DestroyTexture(cart->image);
return 0;
}

Expand All @@ -280,20 +303,6 @@ static int load_cart(SDL_Renderer* renderer, const char* file_name, cart_t* cart
patch_cart_code(cart);
}

cart->image = SDL_CreateTextureFromSurface(renderer, surface);
if (!cart->image)
{
SDL_Log("Couldn't create texture: %s", SDL_GetError());
return 0;
}
SDL_DestroySurface(surface);
stbi_image_free(image_data);

if (!SDL_SetTextureScaleMode(cart->image, SDL_SCALEMODE_NEAREST))
{
SDL_Log("Couldn't set texture scale mode: %s", SDL_GetError());
}

return 1;
}

Expand All @@ -314,12 +323,6 @@ static void destroy_cart(cart_t* cart)
SDL_free(cart->code);
}
cart->code = NULL;

if (cart->data)
{
SDL_free(cart->data);
}
cart->data = NULL;
}

static bool is_function_present(lua_State* L, const char* func_name)
Expand Down Expand Up @@ -432,29 +435,16 @@ static void render_cartridge(SDL_Renderer* renderer)
{
SDL_SetRenderTarget(renderer, NULL);

SDL_FRect source;
SDL_FRect dest;
SDL_FRect frame_dest;

source.x = 16.f;
source.y = 24.f;
source.w = SCREEN_SIZE;
source.h = SCREEN_SIZE;

dest.x = SCREEN_OFFSET_X;
dest.y = SCREEN_OFFSET_Y;
dest.w = SCREEN_SIZE;
dest.h = SCREEN_SIZE;

frame_dest.x = FRAME_OFFSET_X;
frame_dest.y = FRAME_OFFSET_Y;
frame_dest.w = 176.f;
frame_dest.h = 208.f;
dest.x = FRAME_OFFSET_X;
dest.y = FRAME_OFFSET_Y;
dest.w = FRAME_W;
dest.h = FRAME_H;

SDL_SetRenderDrawColor(renderer, 0x31, 0x31, 0x31, 0xff);
SDL_RenderClear(renderer);
SDL_RenderTexture(renderer, frame, NULL, &frame_dest);
SDL_RenderTexture(renderer, cart.image, &source, &dest);
SDL_RenderTexture(renderer, cart.image, NULL, &dest);
}

bool init_core(SDL_Renderer* renderer)
Expand All @@ -466,13 +456,6 @@ bool init_core(SDL_Renderer* renderer)
selection = 0;
prev_selection = !selection;

SDL_snprintf(path, sizeof(path), "%sdata/frame.png", SDL_GetBasePath());
frame = load_image(renderer, path, &width, &height, &bpp);
if (!frame)
{
return false;
}

SDL_snprintf(path, sizeof(path), "%scarts", SDL_GetBasePath());

DIR* dir = opendir(path);
Expand Down Expand Up @@ -524,10 +507,6 @@ void destroy_core(void)
{
SDL_free(available_carts);
}
if (frame)
{
SDL_DestroyTexture(frame);
}
}

bool handle_events(SDL_Renderer* renderer, SDL_Event* event)
Expand Down
2 changes: 0 additions & 2 deletions src/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@
typedef struct cart
{
SDL_Texture* image;
uint8_t* data;
uint32_t size;

uint8_t cart_data[0x8020];
uint8_t* code;
Expand Down
Loading
Loading