mirror of
https://github.com/kichikuou/xsystem35-sdl2.git
synced 2026-10-09 23:58:25 +03:00
Revamp NightDemonDemo
- Fix off-by-one bug in demo number - Use the jpeg extraction function in src/ - Improve alk archive interface
This commit is contained in:
@@ -118,12 +118,6 @@ else()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (HAVE_JPEG)
|
||||
target_sources(modules PRIVATE
|
||||
NightDemonDemo/ndd.c
|
||||
NightDemonDemo/jpeg2surface.c
|
||||
)
|
||||
if (NOT EMSCRIPTEN)
|
||||
target_link_libraries(modules PRIVATE JPEG::JPEG)
|
||||
endif()
|
||||
if (HAVE_JPEG AND NOT EMSCRIPTEN)
|
||||
target_link_libraries(modules PRIVATE JPEG::JPEG)
|
||||
endif()
|
||||
|
||||
@@ -30,9 +30,65 @@
|
||||
#include "xsystem35.h"
|
||||
#include "modules.h"
|
||||
#include "nact.h"
|
||||
#include "alk.h"
|
||||
#include "music.h"
|
||||
#include "sdl_core.h"
|
||||
#include "input.h"
|
||||
#include "ngraph.h"
|
||||
#include "cg.h"
|
||||
#ifdef HAVE_JPEG
|
||||
#include "jpeg.h"
|
||||
#endif
|
||||
|
||||
extern void ndd_init(const char *files[], int n);
|
||||
extern void ndd_run(int demonum);
|
||||
#ifdef HAVE_JPEG
|
||||
|
||||
#define FPS 30
|
||||
|
||||
static const int ndemo_mus[3] = {0, 1, 85};
|
||||
|
||||
static void ndd_run(int demonum) {
|
||||
const char *alk_path = nact->files.alk[demonum + 1];
|
||||
alk_t *alk = alk_new(alk_path);
|
||||
if (alk == NULL) return;
|
||||
|
||||
while (sys_getInputInfo()); // wait for key up
|
||||
|
||||
int mus = ndemo_mus[demonum];
|
||||
if (mus)
|
||||
mus_bgm_play(mus, 0, 100);
|
||||
|
||||
uint32_t start = sdl_getTicks();
|
||||
while (!nact->is_quit) {
|
||||
int i = (sdl_getTicks() - start) / (1000 / FPS);
|
||||
if (i >= alk->datanum)
|
||||
break;
|
||||
|
||||
cgdata *cg = jpeg_extract(alk->entries[i].data, alk->entries[i].size);
|
||||
if (cg) {
|
||||
gr_drawimage16(sf0, cg, 0, 0);
|
||||
ags_updateFull();
|
||||
cgdata_free(cg);
|
||||
} else {
|
||||
WARNING("Cannot decode CG %d in %s\n", i, alk_path);
|
||||
}
|
||||
|
||||
int wait_ms = (i + 1) * (1000 / FPS) - (sdl_getTicks() - start);
|
||||
if (wait_ms > 0) {
|
||||
if (sys_keywait(wait_ms, KEYWAIT_CANCELABLE))
|
||||
break;
|
||||
} else {
|
||||
if (sys_getInputInfo())
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mus)
|
||||
mus_bgm_stop(ndemo_mus[demonum], 0);
|
||||
|
||||
alk_free(alk);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void Init() {
|
||||
int p1 = getCaliValue(); /* ISys3x */
|
||||
@@ -40,9 +96,6 @@ static void Init() {
|
||||
int p3 = getCaliValue(); /* ITimer */
|
||||
int *var = getCaliVariable();
|
||||
|
||||
#ifdef HAVE_JPEG
|
||||
ndd_init(nact->files.alk, 4);
|
||||
#endif
|
||||
*var = 1;
|
||||
|
||||
DEBUG_COMMAND("NightDemonDemo.Init %d,%d,%d,%p:\n", p1, p2, p3, var);
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* jpeg2surface.c:
|
||||
*
|
||||
* Copyright (C) 1997-1998 Masaki Chikama (Wren) <chikama@kasumi.ipl.mech.nagoya-u.ac.jp>
|
||||
* 1998- <masaki-c@is.aist-nara.ac.jp>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
/* $Id: jpeg2surface.c,v 1.2 2003/11/09 15:06:12 chikama Exp $ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <jpeglib.h>
|
||||
#undef max
|
||||
#undef min
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "portab.h"
|
||||
#include "ags.h"
|
||||
#include "surface.h"
|
||||
#include "ngraph.h"
|
||||
|
||||
static void ppm2surface(surface_t *sf, int curscanline, unsigned char *src, int width) {
|
||||
BYTE *dp = GETOFFSET_PIXEL(sf, 0, curscanline);
|
||||
|
||||
switch (sf->depth) {
|
||||
case 16:
|
||||
{
|
||||
WORD *dst = (WORD *)dp;
|
||||
while (width--) {
|
||||
*dst = PIX16(*src, *(src +1), *(src +2));
|
||||
dst++; src+= 3;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 24:
|
||||
case 32:
|
||||
{
|
||||
DWORD *dst = (DWORD *)dp;
|
||||
while (width--) {
|
||||
*dst = PIX24(*src, *(src +1), *(src +2));
|
||||
dst++; src+= 3;
|
||||
}
|
||||
break;
|
||||
}}
|
||||
}
|
||||
|
||||
// sf0 に直接描く(それでも遅いけど)
|
||||
surface_t *jpeg2surface(FILE *fp, int offset) {
|
||||
struct jpeg_decompress_struct cinfo;
|
||||
struct jpeg_error_mgr jerr;
|
||||
int row_stride;
|
||||
surface_t *sf;
|
||||
JSAMPARRAY buffer;
|
||||
|
||||
fseek(fp, offset, SEEK_SET);
|
||||
|
||||
cinfo.err = jpeg_std_error(&jerr);
|
||||
jpeg_create_decompress(&cinfo);
|
||||
|
||||
jpeg_stdio_src(&cinfo, fp);
|
||||
jpeg_read_header(&cinfo, TRUE);
|
||||
|
||||
cinfo.do_fancy_upsampling = FALSE;
|
||||
cinfo.do_block_smoothing = FALSE;
|
||||
|
||||
jpeg_start_decompress(&cinfo);
|
||||
//fprintf(stderr, "width = %d, height = %d\n", cinfo.output_width, cinfo.output_height);
|
||||
|
||||
//sf = sf_create_pixel(cinfo.output_width, cinfo.output_height, sf0->depth);
|
||||
sf = sf0;
|
||||
|
||||
row_stride = cinfo.output_width * cinfo.output_components;
|
||||
buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
|
||||
|
||||
while (cinfo.output_scanline < cinfo.output_height) {
|
||||
jpeg_read_scanlines(&cinfo, buffer, 1);
|
||||
ppm2surface(sf, cinfo.output_scanline -1, buffer[0], cinfo.output_width);
|
||||
}
|
||||
jpeg_finish_decompress(&cinfo);
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
|
||||
return sf;
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
* ndd.c:
|
||||
*
|
||||
* Copyright (C) 1997-1998 Masaki Chikama (Wren) <chikama@kasumi.ipl.mech.nagoya-u.ac.jp>
|
||||
* 1998- <masaki-c@is.aist-nara.ac.jp>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
/* $Id: ndd.c,v 1.2 2003/11/09 15:06:12 chikama Exp $ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "portab.h"
|
||||
#include "ags.h"
|
||||
#include "alk.h"
|
||||
#include "system.h"
|
||||
#include "surface.h"
|
||||
#include "music.h"
|
||||
#include "sdl_core.h"
|
||||
#include "ngraph.h"
|
||||
#include "input.h"
|
||||
|
||||
// 0: AliceSoft
|
||||
// 1: Opening
|
||||
// 2: Meteo
|
||||
|
||||
struct nddemo {
|
||||
const char **fn;
|
||||
alk_t *alk;
|
||||
surface_t *sf[10];
|
||||
};
|
||||
|
||||
static struct nddemo ndd;
|
||||
static int ndemo_alk[3] = {2, 3, 4};
|
||||
static int ndemo_mus[3] = {0, 1, 85};
|
||||
static int ndemo_nums[3] = {150, 603, 467};
|
||||
|
||||
extern surface_t *jpeg2surface(FILE *fp, int offset);
|
||||
|
||||
// ALKファイルの登録
|
||||
void ndd_init(const char *files[], int n) {
|
||||
int i;
|
||||
ndd.fn = malloc(sizeof(char *) * n);
|
||||
|
||||
for (i = 1; i <= n; i++) {
|
||||
ndd.fn[i] = files[i];
|
||||
}
|
||||
}
|
||||
|
||||
// デモ本体
|
||||
void ndd_run(int demonum) {
|
||||
FILE *fp;
|
||||
alk_t *alk;
|
||||
int i, start, ct;
|
||||
|
||||
// ファイルオフセットだけ alk からもらう
|
||||
alk = alk_new(ndd.fn[ndemo_alk[demonum]]);
|
||||
if (alk == NULL) return;
|
||||
|
||||
// libjpeg には FILE* を渡す
|
||||
if (NULL == (fp = fopen(ndd.fn[ndemo_alk[demonum]], "rb"))) {
|
||||
WARNING("%s not found\n", ndd.fn[ndemo_alk[demonum]]);
|
||||
return;
|
||||
}
|
||||
|
||||
// wait keyup
|
||||
while (sys_getInputInfo());
|
||||
|
||||
mus_bgm_play(ndemo_mus[demonum], 0, 100);
|
||||
start = sdl_getTicks();
|
||||
ct = 0;
|
||||
for (i = 0; i <= ndemo_nums[demonum];) {
|
||||
int offset;
|
||||
int cur1, cur = sdl_getTicks();
|
||||
|
||||
offset = alk->offset[i];
|
||||
|
||||
jpeg2surface(fp, offset); ct++;
|
||||
ags_updateFull();
|
||||
|
||||
cur1 = sdl_getTicks();
|
||||
if (cur1 - cur < 33) {
|
||||
if (sys_keywait(33 - (cur1 - cur), KEYWAIT_CANCELABLE)) break;
|
||||
} else {
|
||||
if (sys_getInputInfo()) break;
|
||||
}
|
||||
|
||||
i = (cur - start) / 33;
|
||||
}
|
||||
|
||||
NOTICE("%d/%d processed\n", ct, ndemo_nums[demonum]);
|
||||
mus_bgm_stop(ndemo_mus[demonum], 0);
|
||||
|
||||
fclose(fp);
|
||||
alk_free(alk);
|
||||
}
|
||||
+9
-22
@@ -34,9 +34,6 @@
|
||||
#include "alk.h"
|
||||
|
||||
alk_t *alk_new(const char *path) {
|
||||
alk_t *alk;
|
||||
int i;
|
||||
|
||||
mmap_t *m = map_file(path);
|
||||
|
||||
if (0 != strncmp(m->addr, "ALK0", 4)) {
|
||||
@@ -45,30 +42,20 @@ alk_t *alk_new(const char *path) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
alk = calloc(1, sizeof(alk_t));
|
||||
int nr_entries = LittleEndian_getDW(m->addr, 4);
|
||||
|
||||
alk_t *alk = malloc(sizeof(alk_t) + sizeof(struct alk_entry) * nr_entries);
|
||||
alk->mmap = m;
|
||||
alk->datanum = LittleEndian_getDW(m->addr, 4);
|
||||
alk->offset = malloc(sizeof(int) * alk->datanum);
|
||||
|
||||
for (i = 0; i < alk->datanum; i++) {
|
||||
alk->offset[i] = LittleEndian_getDW(m->addr, 8 + i * 8);
|
||||
alk->datanum = nr_entries;
|
||||
|
||||
for (int i = 0; i < nr_entries; i++) {
|
||||
alk->entries[i].data = (uint8_t *)m->addr + LittleEndian_getDW(m->addr, 8 + i * 8);
|
||||
alk->entries[i].size = LittleEndian_getDW(m->addr, 8 + i * 8 + 4);
|
||||
}
|
||||
|
||||
return alk;
|
||||
}
|
||||
|
||||
int alk_free(alk_t *alk) {
|
||||
if (alk == NULL) return OK;
|
||||
|
||||
void alk_free(alk_t *alk) {
|
||||
unmap_file(alk->mmap);
|
||||
free(alk->offset);
|
||||
free(alk);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
char *alk_get(alk_t *alk, int no) {
|
||||
if (no >= alk->datanum) return NULL;
|
||||
|
||||
return (char *)alk->mmap->addr + alk->offset[no];
|
||||
}
|
||||
|
||||
+9
-16
@@ -25,27 +25,20 @@
|
||||
#ifndef __ALK_H__
|
||||
#define __ALK_H__
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include "mmap.h"
|
||||
|
||||
/*
|
||||
.ALK データ構造
|
||||
|
||||
char[4] sig = "ALK0"; シグネチャ
|
||||
int32 num = ファイル数
|
||||
int32 offset; 個々のファイルのファイルの先頭からのオフセット
|
||||
int32 size; 個々のファイルの大きさ(in bytes)
|
||||
*/
|
||||
struct alk_entry {
|
||||
void *data;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
mmap_t *mmap; /* mmap したファイル */
|
||||
int datanum; /* .alk ファイル中のファイル数 */
|
||||
int *offset; /* 各ファイルへのオフセット */
|
||||
mmap_t *mmap;
|
||||
int datanum;
|
||||
struct alk_entry entries[];
|
||||
} alk_t;
|
||||
|
||||
extern alk_t *alk_new(const char *path);
|
||||
extern int alk_free(alk_t *alk);
|
||||
extern char *alk_get(alk_t *alk, int no);
|
||||
alk_t *alk_new(const char *path);
|
||||
void alk_free(alk_t *alk);
|
||||
|
||||
#endif /* __ALK_H__ */
|
||||
|
||||
+1
-6
@@ -127,12 +127,7 @@ surface_t *sf_getcg(void *b, size_t size) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (cg->pic) free(cg->pic);
|
||||
if (cg->pal) free(cg->pal);
|
||||
if (cg->alpha) free(cg->alpha);
|
||||
free(cg);
|
||||
|
||||
cgdata_free(cg);
|
||||
return sf;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,6 @@ static cacher *cacheid;
|
||||
/* static methods */
|
||||
static CG_TYPE check_cgformat(BYTE *data);
|
||||
static void set_vspbank(BYTE *pic, int bank, int width, int height);
|
||||
static void cgdata_free(cgdata *cg);
|
||||
static MyPoint set_display_loc(cgdata *cg);
|
||||
static void clear_display_loc();
|
||||
static void display_cg(cgdata *cg, int x, int y);
|
||||
@@ -116,7 +115,7 @@ static void set_vspbank(BYTE *pic, int bank, int width, int height) {
|
||||
* Free data
|
||||
* cg: freeing data object
|
||||
*/
|
||||
static void cgdata_free(cgdata *cg) {
|
||||
void cgdata_free(cgdata *cg) {
|
||||
if (cg->pic) free(cg->pic);
|
||||
if (cg->pal) free(cg->pal);
|
||||
if (cg->alpha) free(cg->alpha);
|
||||
|
||||
@@ -83,6 +83,7 @@ extern void cg_load_with_alpha(int cgno, int shadowno);
|
||||
extern int cg_load_with_filename(char *fname_utf8, int x, int y);
|
||||
extern void cg_get_info(int no, MyRectangle *info);
|
||||
extern void cg_clear_display_loc();
|
||||
extern void cgdata_free(cgdata *cg);
|
||||
|
||||
extern int cg_vspPB;
|
||||
extern int cg_fflg;
|
||||
|
||||
Reference in New Issue
Block a user