mirror of
https://github.com/kichikuou/xsystem35-sdl2.git
synced 2026-10-07 14:18:04 +03:00
Add webp CG support
Used in the MangaGamer version of Rance 5D. The logic for the OVER chunk was taken from libsys4.
This commit is contained in:
@@ -15,7 +15,7 @@ jobs:
|
||||
- name: Install Deps
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install libgtk-3-dev libsdl2-dev libsdl2-ttf-dev libsdl2-mixer-dev libportmidi-dev libcjson-dev
|
||||
sudo apt install libgtk-3-dev libsdl2-dev libsdl2-ttf-dev libsdl2-mixer-dev libwebp-dev libportmidi-dev libcjson-dev
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
echo PATH: $PATH
|
||||
|
||||
- name: Install Deps
|
||||
run: pacman -S --noconfirm ${{ matrix.package }}-SDL2 ${{ matrix.package }}-SDL2_ttf ${{ matrix.package }}-SDL2_mixer ${{ matrix.package }}-libjpeg-turbo ${{ matrix.package }}-cjson ${{ matrix.package }}-nsis ${{ matrix.package }}-ntldd-git
|
||||
run: pacman -S --noconfirm ${{ matrix.package }}-SDL2 ${{ matrix.package }}-SDL2_ttf ${{ matrix.package }}-SDL2_mixer ${{ matrix.package }}-libjpeg-turbo ${{ matrix.package }}-libwebp ${{ matrix.package }}-cjson ${{ matrix.package }}-nsis ${{ matrix.package }}-ntldd-git
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
@@ -65,6 +65,11 @@ else()
|
||||
set(HAVE_JPEG 1)
|
||||
endif()
|
||||
|
||||
optional_pkg_check_modules(WEBP IMPORTED_TARGET libwebp)
|
||||
if (WEBP_FOUND)
|
||||
set(HAVE_WEBP 1)
|
||||
endif()
|
||||
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads)
|
||||
if (CMAKE_USE_PTHREADS_INIT)
|
||||
|
||||
@@ -8,7 +8,7 @@ Prebuilt binaries for Windows and Android can be downloaded from the [Releases](
|
||||
## Build
|
||||
### Linux (Debian / Ubuntu)
|
||||
|
||||
$ sudo apt install build-essential cmake libgtk-3-dev libsdl2-dev libsdl2-ttf-dev libsdl2-mixer-dev libcjson-dev
|
||||
$ sudo apt install build-essential cmake libgtk-3-dev libsdl2-dev libsdl2-ttf-dev libsdl2-mixer-dev libwebp-dev libcjson-dev
|
||||
$ mkdir -p out/debug
|
||||
$ cd out/debug
|
||||
$ cmake -DCMAKE_BUILD_TYPE=Debug ../../
|
||||
@@ -18,7 +18,7 @@ Prebuilt binaries for Windows and Android can be downloaded from the [Releases](
|
||||
|
||||
[Homebrew](https://brew.sh/index_ja) is needed.
|
||||
|
||||
$ brew install cmake pkg-config sdl2 sdl2_mixer sdl2_ttf libjpeg cjson
|
||||
$ brew install cmake pkg-config sdl2 sdl2_mixer sdl2_ttf libjpeg webp cjson
|
||||
$ mkdir -p out/debug
|
||||
$ cd out/debug
|
||||
$ cmake -DCMAKE_BUILD_TYPE=Debug ../../
|
||||
@@ -28,7 +28,7 @@ Prebuilt binaries for Windows and Android can be downloaded from the [Releases](
|
||||
|
||||
[MSYS2](https://www.msys2.org) is needed.
|
||||
|
||||
$ pacman -S cmake mingw-w64-x86_64-cmake mingw-w64-x86_64-SDL2 mingw-w64-x86_64-SDL2_ttf mingw-w64-x86_64-SDL2_mixer mingw-w64-x86_64-libjpeg-turbo mingw-w64-x86_64-cjson
|
||||
$ pacman -S cmake mingw-w64-x86_64-cmake mingw-w64-x86_64-SDL2 mingw-w64-x86_64-SDL2_ttf mingw-w64-x86_64-SDL2_mixer mingw-w64-x86_64-libjpeg-turbo mingw-w64-x86_64-libwebp mingw-w64-x86_64-cjson
|
||||
$ mkdir -p out/debug
|
||||
$ cd out/debug
|
||||
$ cmake -G"MSYS Makefiles" -DCMAKE_BUILD_TYPE=Debug ../../
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#cmakedefine HAVE_SDLJOY @HAVE_SDLJOY@
|
||||
#cmakedefine HAVE_SIGACTION @HAVE_SIGACTION@
|
||||
#cmakedefine HAVE_UNAME @HAVE_UNAME@
|
||||
#cmakedefine HAVE_WEBP @HAVE_WEBP@
|
||||
|
||||
#define DEFAULT_GOTHIC_TTF "@DEFAULT_FONT_PATH@MTLc3m.ttf"
|
||||
#define DEFAULT_MINCHO_TTF "@DEFAULT_FONT_PATH@mincho.otf"
|
||||
|
||||
@@ -86,7 +86,7 @@ static surface_t *smask_get(int no) {
|
||||
|
||||
if (i == am->datanum) return NULL;
|
||||
|
||||
return sf_getcg(am->mmap->addr + am->offset[i]);
|
||||
return sf_getcg(am->mmap->addr + am->offset[i], 0 /*FIXME*/);
|
||||
}
|
||||
|
||||
// ベースになるマスクの alpha 値を拡大して取り出す
|
||||
|
||||
+18
-5
@@ -33,6 +33,9 @@
|
||||
#include "ags.h"
|
||||
#include "pms.h"
|
||||
#include "qnt.h"
|
||||
#ifdef HAVE_WEBP
|
||||
#include "webp.h"
|
||||
#endif
|
||||
#include "ngraph.h"
|
||||
#include "dri.h"
|
||||
#include "ald_manager.h"
|
||||
@@ -50,6 +53,10 @@ static CG_TYPE check_cgformat(BYTE *data) {
|
||||
return ALCG_PMS8;
|
||||
} else if (pms64k_checkfmt(data)) {
|
||||
return ALCG_PMS16;
|
||||
#ifdef HAVE_WEBP
|
||||
} else if (webp_checkfmt(data)) {
|
||||
return ALCG_WEBP;
|
||||
#endif
|
||||
}
|
||||
return ALCG_UNKNOWN;
|
||||
}
|
||||
@@ -61,7 +68,7 @@ static CG_TYPE check_cgformat(BYTE *data) {
|
||||
* @return CG が展開された surface
|
||||
* 未知の形式のときは NULL が返る
|
||||
*/
|
||||
surface_t *sf_getcg(void *b) {
|
||||
surface_t *sf_getcg(void *b, size_t size) {
|
||||
surface_t *sf = NULL;
|
||||
int type;
|
||||
cgdata *cg = NULL;
|
||||
@@ -77,6 +84,11 @@ surface_t *sf_getcg(void *b) {
|
||||
case ALCG_QNT:
|
||||
cg = qnt_extract(b);
|
||||
break;
|
||||
#ifdef HAVE_WEBP
|
||||
case ALCG_WEBP:
|
||||
cg = webp_extract(b, size);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -93,7 +105,7 @@ surface_t *sf_getcg(void *b) {
|
||||
break;
|
||||
|
||||
case ALCG_PMS16:
|
||||
if (cg->alpha) {
|
||||
if (cg->alpha) {
|
||||
sf = sf_create_surface(cg->width, cg->height, sf0->depth);
|
||||
gr_drawimage16(sf, cg, cg->x, cg->y);
|
||||
gr_draw_amap(sf, cg->x, cg->y, cg->alpha, cg->width, cg->height, cg->width);
|
||||
@@ -103,7 +115,8 @@ surface_t *sf_getcg(void *b) {
|
||||
}
|
||||
break;
|
||||
|
||||
case ALCG_QNT:
|
||||
case ALCG_QNT:
|
||||
case ALCG_WEBP:
|
||||
if (cg->alpha) {
|
||||
sf = sf_create_surface(cg->width, cg->height, sf0->depth);
|
||||
gr_drawimage24(sf, cg, cg->x, cg->y);
|
||||
@@ -112,7 +125,7 @@ surface_t *sf_getcg(void *b) {
|
||||
sf = sf_create_pixel(cg->width, cg->height, sf0->depth);
|
||||
gr_drawimage24(sf, cg, cg->x, cg->y);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
if (cg->pic) free(cg->pic);
|
||||
@@ -137,7 +150,7 @@ surface_t *sf_loadcg_no(int no) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sf = sf_getcg(dfile->data);
|
||||
sf = sf_getcg(dfile->data, dfile->size);
|
||||
|
||||
ald_freedata(dfile);
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ extern void gr_drawimage16(surface_t *ds, cgdata *cg, int x, int y);
|
||||
|
||||
|
||||
/* defined in cg.c */
|
||||
extern surface_t *sf_getcg(void *buf);
|
||||
extern surface_t *sf_getcg(void *buf, size_t size);
|
||||
extern surface_t *sf_loadcg_no(int no);
|
||||
|
||||
|
||||
|
||||
@@ -46,6 +46,10 @@ if (HAVE_JPEG)
|
||||
target_link_libraries(xsystem35 PRIVATE JPEG::JPEG)
|
||||
endif()
|
||||
endif()
|
||||
if (HAVE_WEBP)
|
||||
target_sources(xsystem35 PRIVATE webp.c)
|
||||
target_link_libraries(xsystem35 PRIVATE PkgConfig::WEBP)
|
||||
endif()
|
||||
|
||||
# Music
|
||||
target_sources(xsystem35 PRIVATE
|
||||
|
||||
@@ -32,13 +32,14 @@
|
||||
*/
|
||||
typedef enum {
|
||||
ALCG_UNKNOWN = 1,
|
||||
ALCG_VSP = 2,
|
||||
ALCG_PMS8 = 3,
|
||||
ALCG_PMS16 = 4,
|
||||
ALCG_BMP8 = 5,
|
||||
ALCG_BMP24 = 6,
|
||||
ALCG_QNT = 7,
|
||||
ALCG_JPEG = 8,
|
||||
ALCG_VSP,
|
||||
ALCG_PMS8,
|
||||
ALCG_PMS16,
|
||||
ALCG_BMP8,
|
||||
ALCG_BMP24,
|
||||
ALCG_QNT,
|
||||
ALCG_JPEG,
|
||||
ALCG_WEBP,
|
||||
} CG_TYPE;
|
||||
|
||||
/*
|
||||
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (C) 2021 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <webp/decode.h>
|
||||
|
||||
#include "system.h"
|
||||
#include "webp.h"
|
||||
#include "dri.h"
|
||||
#include "ald_manager.h"
|
||||
#include "LittleEndian.h"
|
||||
|
||||
boolean webp_checkfmt(BYTE *data) {
|
||||
if (data[0] != 'R' || data[1] != 'I' || data[2] != 'F' || data[3] != 'F')
|
||||
return FALSE;
|
||||
if (data[8] != 'W' || data[9] != 'E' || data[10] != 'B' || data[11] != 'P')
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int get_base_cg(uint8_t *data, size_t size) {
|
||||
if (size < 12)
|
||||
return 0;
|
||||
if (data[size-12] != 'O' || data[size-11] != 'V' || data[size-10] != 'E' || data[size-9] != 'R')
|
||||
return 0;
|
||||
int uk = LittleEndian_getDW(data, size-8); // size?
|
||||
if (uk != 4)
|
||||
WARNING("WEBP: expected 0x4 preceding base CG number, got %d\n", uk);
|
||||
return LittleEndian_getDW(data, size-4);
|
||||
}
|
||||
|
||||
static uint8_t *webp_load(uint8_t *data, size_t size, int *width, int *height, int *has_alpha) {
|
||||
uint8_t *pixels = WebPDecodeRGBA(data, size, width, height);
|
||||
if (!pixels) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
WebPBitstreamFeatures features;
|
||||
WebPGetFeatures(data, size, &features);
|
||||
*has_alpha = features.has_alpha;
|
||||
|
||||
int base = get_base_cg(data, size);
|
||||
if (!base)
|
||||
return pixels;
|
||||
|
||||
dridata *dfile = ald_getdata(DRIFILE_CG, base - 1);
|
||||
if (!dfile) {
|
||||
WARNING("Cannot load base CG %d\n", base - 1);
|
||||
return pixels;
|
||||
}
|
||||
|
||||
int base_width, base_height, base_has_alpha;
|
||||
uint8_t *base_pixels = webp_load(dfile->data, dfile->size, &base_width, &base_height, &base_has_alpha);
|
||||
ald_freedata(dfile);
|
||||
if (!base_pixels) {
|
||||
WARNING("Cannot decode base CG %d\n", base - 1);
|
||||
return pixels;
|
||||
}
|
||||
if (*width != base_width || *height != base_height) {
|
||||
WARNING("webp base CG dimensions don't match: (%d,%d) / (%d,%d)\n",
|
||||
base_width, base_height, *width, *height);
|
||||
WebPFree(base_pixels);
|
||||
return pixels;
|
||||
}
|
||||
*has_alpha |= base_has_alpha;
|
||||
|
||||
uint8_t *p = pixels;
|
||||
uint8_t *bp = base_pixels;
|
||||
for (int n = base_width * base_height; n > 0; n--) {
|
||||
if (p[0] == 255 && p[1] == 0 && p[2] == 255) {
|
||||
p[0] = bp[0];
|
||||
p[1] = bp[1];
|
||||
p[2] = bp[2];
|
||||
p[3] = bp[3];
|
||||
}
|
||||
p += 4;
|
||||
bp += 4;
|
||||
}
|
||||
WebPFree(base_pixels);
|
||||
return pixels;
|
||||
}
|
||||
|
||||
static void rgba_to_rgb_and_alpha(uint8_t *rgba, uint8_t *rgb, uint8_t *alpha, int nr_pixels) {
|
||||
for (int i = 0; i < nr_pixels; i++) {
|
||||
*rgb++ = *rgba++;
|
||||
*rgb++ = *rgba++;
|
||||
*rgb++ = *rgba++;
|
||||
*alpha++ = *rgba++;
|
||||
}
|
||||
}
|
||||
|
||||
cgdata *webp_extract(BYTE *data, size_t size) {
|
||||
int width, height, has_alpha;
|
||||
uint8_t *rgba = webp_load(data, size, &width, &height, &has_alpha);
|
||||
if (!rgba) {
|
||||
WARNING("webp image decode failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cgdata *cg = calloc(1, sizeof(cgdata));
|
||||
cg->type = ALCG_WEBP;
|
||||
cg->width = width;
|
||||
cg->height = height;
|
||||
cg->pic = malloc(cg->width * cg->height * 3);
|
||||
cg->alpha = malloc(cg->width * cg->height);
|
||||
rgba_to_rgb_and_alpha(rgba, cg->pic, cg->alpha, cg->width * cg->height);
|
||||
if (!has_alpha) {
|
||||
free(cg->alpha);
|
||||
cg->alpha = NULL;
|
||||
}
|
||||
WebPFree(rgba);
|
||||
|
||||
return cg;
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2021 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __WEBP_H__
|
||||
#define __WEBP_H__
|
||||
|
||||
#include "cg.h"
|
||||
|
||||
boolean webp_checkfmt(BYTE *data);
|
||||
cgdata *webp_extract(BYTE *data, size_t size);
|
||||
|
||||
#endif // __WEBP_H__
|
||||
Reference in New Issue
Block a user