I’m writing a visual novel engine. It’s actually a re-implementation of an engine used by a Japanese company. I’m trying to use libass (alpha substation) as subtitles, but I don’t know how to convert the ASS bitmap array to an SDL texture.
I attach here my code and also the ASS struct for the subtitle bitmap
int playText(void *import)
{
kotonohaData::acessMapper *importedTo = static_cast<kotonohaData::acessMapper *>(import);
importedTo->root->log0->appendLog("(Text) - Start");
kotonohaTime::delay(1000);
char file[64] = "test.ass";
char *subfile = file;
ASS_Library *ass_library;
ASS_Renderer *ass_renderer;
int frame_w = 1280;
int frame_h = 720;
ass_library = ass_library_init();
if (!ass_library)
{
printf("ass_library_init failed!\n");
exit(1);
}
ass_set_extract_fonts(ass_library, 1);
ass_renderer = ass_renderer_init(ass_library);
if (!ass_renderer)
{
printf("ass_renderer_init failed!\n");
exit(1);
}
ass_set_storage_size(ass_renderer, frame_w, frame_h);
ass_set_frame_size(ass_renderer, frame_w, frame_h);
ass_set_fonts(ass_renderer, NULL, "sans-serif", ASS_FONTPROVIDER_AUTODETECT, NULL, 1);
ASS_Track *track = ass_read_file(ass_library, subfile, NULL);
if (!track)
{
printf("track init failed!\n");
return 1;
}
importedTo->root->log0->appendLog("(Text) - End");
while (importedTo->control->outCode == -1)
{
if (importedTo->control->display[2])
{
ASS_Image *img = ass_render_frame(ass_renderer, track, (int)(5 * 1000), NULL);
SDL_Texture *texture = nullptr;
texture = SDL_CreateTexture(importedTo->root->renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, img->w, img->h);
SDL_UpdateTexture(texture, nullptr, img->bitmap, img->w * sizeof(Uint32));
SDL_Rect rect = {0, 0, frame_h, frame_w};
SDL_RenderCopy(importedTo->root->renderer, texture, &rect, NULL);
SDL_DestroyTexture(texture);
importedTo->control->display[2] = false;
importedTo->control->display[3] = true;
}
}
ass_free_track(track);
ass_renderer_done(ass_renderer);
ass_library_done(ass_library);
importedTo->root->log0->appendLog("(Text) - End");
return 0;
};```
/*
-
A linked list of images produced by an ass renderer.
-
These images have to be rendered in-order for the correct screen
-
composition. The libass renderer clips these bitmaps to the frame size.
-
w/h can be zero, in this case the bitmap should not be rendered at all.
-
The last bitmap row is not guaranteed to be padded up to stride size,
-
e.g. in the worst case a bitmap has the size stride * (h - 1) + w.
*/
typedef struct ass_image {
int w, h; // Bitmap width/height
int stride; // Bitmap stride
unsigned char bitmap; // 1bpp strideh alpha buffer
// Note: the last row may not be padded to
// bitmap stride!
uint32_t color; // Bitmap color and alpha, RGBA
// For full VSFilter compatibility, the value
// must be transformed as described in
// ass_types.h for ASS_YCbCrMatrix
int dst_x, dst_y; // Bitmap placement inside the video framestruct ass_image *next; // Next image, or NULL
enum {
IMAGE_TYPE_CHARACTER,
IMAGE_TYPE_OUTLINE,
IMAGE_TYPE_SHADOW
} type;// New fields can be added here in new ABI-compatible library releases.
} ASS_Image;