Convert linebreaks from CRLF to LF

This commit is contained in:
kichikuou
2022-04-03 11:34:48 +09:00
parent 82ce12e82c
commit cc75dd7c94
34 changed files with 10891 additions and 10891 deletions
+59 -59
View File
@@ -1,59 +1,59 @@
/*
ALICE SOFT SYSTEM 3 for Win32
[ Common Header ]
*/
#ifndef _COMMON_H_
#define _COMMON_H_
#include <SDL.h>
#include <assert.h>
#include <limits.h>
#include <stdio.h>
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#else
#define EMSCRIPTEN_KEEPALIVE
#endif
#define FONT_RESOURCE_NAME "MTLc3m.ttf"
// type definition
typedef uint8_t uint8;
typedef uint16_t uint16;
typedef uint32_t uint32;
typedef int8_t int8;
typedef int16_t int16;
typedef int32_t int32;
#define ERROR(fmt, ...) \
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s:%d: " fmt, __func__, __LINE__, ##__VA_ARGS__)
#define WARNING(fmt, ...) \
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "%s:%d: " fmt, __func__, __LINE__, ##__VA_ARGS__)
#define NOTICE SDL_Log
#ifndef WIN32
#define _MAX_PATH PATH_MAX
#define sscanf_s sscanf
#define sprintf_s snprintf
inline void strcpy_s(char* dst, size_t n, const char* src)
{
strncpy(dst, src, n);
dst[n - 1] = '\0';
}
#endif // !WIN32
#ifdef _MSC_VER
#define strcasecmp _stricmp
#endif
// resource.cpp
SDL_RWops* open_resource(const char* name, const char* type);
SDL_RWops* open_file(const char* name);
#endif
/*
ALICE SOFT SYSTEM 3 for Win32
[ Common Header ]
*/
#ifndef _COMMON_H_
#define _COMMON_H_
#include <SDL.h>
#include <assert.h>
#include <limits.h>
#include <stdio.h>
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#else
#define EMSCRIPTEN_KEEPALIVE
#endif
#define FONT_RESOURCE_NAME "MTLc3m.ttf"
// type definition
typedef uint8_t uint8;
typedef uint16_t uint16;
typedef uint32_t uint32;
typedef int8_t int8;
typedef int16_t int16;
typedef int32_t int32;
#define ERROR(fmt, ...) \
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s:%d: " fmt, __func__, __LINE__, ##__VA_ARGS__)
#define WARNING(fmt, ...) \
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "%s:%d: " fmt, __func__, __LINE__, ##__VA_ARGS__)
#define NOTICE SDL_Log
#ifndef WIN32
#define _MAX_PATH PATH_MAX
#define sscanf_s sscanf
#define sprintf_s snprintf
inline void strcpy_s(char* dst, size_t n, const char* src)
{
strncpy(dst, src, n);
dst[n - 1] = '\0';
}
#endif // !WIN32
#ifdef _MSC_VER
#define strcasecmp _stricmp
#endif
// resource.cpp
SDL_RWops* open_resource(const char* name, const char* type);
SDL_RWops* open_file(const char* name);
#endif
+162 -162
View File
@@ -1,162 +1,162 @@
/*
ALICE SOFT SYSTEM 3 for Win32
[ File I/O ]
*/
#include "fileio.h"
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#ifndef _WIN32
#include <dirent.h>
#endif
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
std::string FILEIO::savedir = ".";
namespace {
std::string FindFile(const std::string& dir, const char* filename) {
std::string path = dir + "/" + filename;
#ifndef _WIN32
// Case-insensitive search for files in `dir`.
DIR* d = opendir(dir.c_str());
if (!d)
return path;
while (struct dirent* entry = readdir(d)) {
if (strcasecmp(filename, entry->d_name) == 0)
path = dir + "/" + entry->d_name;
}
closedir(d);
#endif
return path;
}
} // namespace
void FILEIO::SetSaveDir(const std::string& dir)
{
savedir = dir;
while (!savedir.empty() && savedir.back() == '/')
savedir.pop_back();
}
int FILEIO::StatSavedata(const char* filename, struct stat* buf)
{
return stat(FindFile(savedir, filename).c_str(), buf);
}
FILEIO::~FILEIO(void)
{
if(fp != NULL) {
Fclose();
}
}
bool FILEIO::Fopen(const char *file_name, int mode)
{
mode_ = mode;
std::string path =
FindFile((mode & FILEIO_SAVEDATA) ? savedir : ".", file_name);
mode &= ~FILEIO_SAVEDATA;
if(fp != NULL) {
Fclose();
}
fp = NULL;
if(mode == FILEIO_READ_BINARY) {
fp = fopen(path.c_str(), "rb");
} else if(mode == FILEIO_WRITE_BINARY) {
fp = fopen(path.c_str(), "wb");
}
return (fp != NULL);
}
void FILEIO::Fclose()
{
if(fp) {
fclose(fp);
}
fp = NULL;
#ifdef __EMSCRIPTEN__
if (mode_ & FILEIO_WRITE_BINARY)
EM_ASM( xsystem35.shell.syncfs(); );
#endif
}
uint32 FILEIO::Fseek(long offset, int origin)
{
uint32 val = 0xFFFFFFFF;
if(origin == FILEIO_SEEK_CUR) {
val = fseek(fp, offset, SEEK_CUR);
} else if(origin == FILEIO_SEEK_END) {
val = fseek(fp, offset, SEEK_END);
} else if(origin == FILEIO_SEEK_SET) {
val = fseek(fp, offset, SEEK_SET);
}
return val;
}
uint32 FILEIO::Ftell()
{
return ftell(fp);
}
size_t FILEIO::Fread(void* buffer, uint32 size, uint32 count)
{
return fread(buffer, size, count, fp);
}
size_t FILEIO::Fwrite(void* buffer, uint32 size, uint32 count)
{
return fwrite(buffer, size, count, fp);
}
int FILEIO::Fgetc()
{
return fgetc(fp);
}
int FILEIO::Fgetw()
{
int val = Fgetc();
return val | (Fgetc() << 8);
}
void FILEIO::Fgets(char *dest, int length)
{
int p = 0;
for(;;) {
int c = Fgetc();
if(c == 0x0d || c == EOF) {
break;
}
if(c != 0x0a) {
if(p < length + 1) {
dest[p++] = c;
}
}
}
dest[p] = '\0';
}
void FILEIO::Fputc(int c)
{
fputc(c, fp);
}
void FILEIO::Fputw(int w)
{
Fputc(w & 0xff);
Fputc((w >> 8) & 0xff);
}
/*
ALICE SOFT SYSTEM 3 for Win32
[ File I/O ]
*/
#include "fileio.h"
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#ifndef _WIN32
#include <dirent.h>
#endif
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
std::string FILEIO::savedir = ".";
namespace {
std::string FindFile(const std::string& dir, const char* filename) {
std::string path = dir + "/" + filename;
#ifndef _WIN32
// Case-insensitive search for files in `dir`.
DIR* d = opendir(dir.c_str());
if (!d)
return path;
while (struct dirent* entry = readdir(d)) {
if (strcasecmp(filename, entry->d_name) == 0)
path = dir + "/" + entry->d_name;
}
closedir(d);
#endif
return path;
}
} // namespace
void FILEIO::SetSaveDir(const std::string& dir)
{
savedir = dir;
while (!savedir.empty() && savedir.back() == '/')
savedir.pop_back();
}
int FILEIO::StatSavedata(const char* filename, struct stat* buf)
{
return stat(FindFile(savedir, filename).c_str(), buf);
}
FILEIO::~FILEIO(void)
{
if(fp != NULL) {
Fclose();
}
}
bool FILEIO::Fopen(const char *file_name, int mode)
{
mode_ = mode;
std::string path =
FindFile((mode & FILEIO_SAVEDATA) ? savedir : ".", file_name);
mode &= ~FILEIO_SAVEDATA;
if(fp != NULL) {
Fclose();
}
fp = NULL;
if(mode == FILEIO_READ_BINARY) {
fp = fopen(path.c_str(), "rb");
} else if(mode == FILEIO_WRITE_BINARY) {
fp = fopen(path.c_str(), "wb");
}
return (fp != NULL);
}
void FILEIO::Fclose()
{
if(fp) {
fclose(fp);
}
fp = NULL;
#ifdef __EMSCRIPTEN__
if (mode_ & FILEIO_WRITE_BINARY)
EM_ASM( xsystem35.shell.syncfs(); );
#endif
}
uint32 FILEIO::Fseek(long offset, int origin)
{
uint32 val = 0xFFFFFFFF;
if(origin == FILEIO_SEEK_CUR) {
val = fseek(fp, offset, SEEK_CUR);
} else if(origin == FILEIO_SEEK_END) {
val = fseek(fp, offset, SEEK_END);
} else if(origin == FILEIO_SEEK_SET) {
val = fseek(fp, offset, SEEK_SET);
}
return val;
}
uint32 FILEIO::Ftell()
{
return ftell(fp);
}
size_t FILEIO::Fread(void* buffer, uint32 size, uint32 count)
{
return fread(buffer, size, count, fp);
}
size_t FILEIO::Fwrite(void* buffer, uint32 size, uint32 count)
{
return fwrite(buffer, size, count, fp);
}
int FILEIO::Fgetc()
{
return fgetc(fp);
}
int FILEIO::Fgetw()
{
int val = Fgetc();
return val | (Fgetc() << 8);
}
void FILEIO::Fgets(char *dest, int length)
{
int p = 0;
for(;;) {
int c = Fgetc();
if(c == 0x0d || c == EOF) {
break;
}
if(c != 0x0a) {
if(p < length + 1) {
dest[p++] = c;
}
}
}
dest[p] = '\0';
}
void FILEIO::Fputc(int c)
{
fputc(c, fp);
}
void FILEIO::Fputw(int w)
{
Fputc(w & 0xff);
Fputc((w >> 8) & 0xff);
}
+48 -48
View File
@@ -1,48 +1,48 @@
/*
ALICE SOFT SYSTEM 3 for Win32
[ File I/O ]
*/
#ifndef _FILEIO_H_
#define _FILEIO_H_
#include <string>
#include <stdio.h>
#include <sys/stat.h>
#include "common.h"
#define FILEIO_READ_BINARY 1
#define FILEIO_WRITE_BINARY 2
#define FILEIO_SAVEDATA 4
#define FILEIO_SEEK_SET 0
#define FILEIO_SEEK_CUR 1
#define FILEIO_SEEK_END 2
class FILEIO
{
private:
static std::string savedir;
FILE* fp;
int mode_;
public:
FILEIO() : fp(NULL), mode_(0) {}
~FILEIO();
static void SetSaveDir(const std::string& dir);
static int StatSavedata(const char* filename, struct stat* buf);
bool Fopen(const char *file_name, int mode);
void Fclose();
uint32 Fseek(long offset, int origin);
uint32 Ftell();
size_t Fread(void* buffer, uint32 size, uint32 count);
size_t Fwrite(void* buffer, uint32 size, uint32 count);
int Fgetc();
int Fgetw();
void Fgets(char* dest, int length);
void Fputc(int c);
void Fputw(int w);
};
#endif
/*
ALICE SOFT SYSTEM 3 for Win32
[ File I/O ]
*/
#ifndef _FILEIO_H_
#define _FILEIO_H_
#include <string>
#include <stdio.h>
#include <sys/stat.h>
#include "common.h"
#define FILEIO_READ_BINARY 1
#define FILEIO_WRITE_BINARY 2
#define FILEIO_SAVEDATA 4
#define FILEIO_SEEK_SET 0
#define FILEIO_SEEK_CUR 1
#define FILEIO_SEEK_END 2
class FILEIO
{
private:
static std::string savedir;
FILE* fp;
int mode_;
public:
FILEIO() : fp(NULL), mode_(0) {}
~FILEIO();
static void SetSaveDir(const std::string& dir);
static int StatSavedata(const char* filename, struct stat* buf);
bool Fopen(const char *file_name, int mode);
void Fclose();
uint32 Fseek(long offset, int origin);
uint32 Ftell();
size_t Fread(void* buffer, uint32 size, uint32 count);
size_t Fwrite(void* buffer, uint32 size, uint32 count);
int Fgetc();
int Fgetw();
void Fgets(char* dest, int length);
void Fputc(int c);
void Fputw(int w);
};
#endif
+234 -234
View File
@@ -1,234 +1,234 @@
/*
ALICE SOFT SYSTEM 3 for Win32
[ MAKO ]
*/
#include <memory>
#include <SDL.h>
#include <SDL_mixer.h>
#include "mako.h"
#include "mako_midi.h"
#include "fm/mako_fmgen.h"
#include "../config.h"
#include "dri.h"
// MIX_INIT_FLUIDSYNTH was renamed to MIX_INIT_MID in SDL_mixer 2.0.2
#if (SDL_MIXER_MAJOR_VERSION == 2) && (SDL_MIXER_MINOR_VERSION == 0) && (SDL_MIXER_PATCHLEVEL < 2)
#define MIX_INIT_MID MIX_INIT_FLUIDSYNTH
#endif
namespace {
const int SAMPLE_RATE = 44100;
std::vector<uint8> smf;
Mix_Music *mix_music;
Mix_Chunk *mix_chunk;
SDL_mutex* fm_mutex;
std::unique_ptr<MakoFMgen> fm;
void FMHook(void *udata, Uint8 *stream, int len) {
SDL_LockMutex(fm_mutex);
fm->Process(reinterpret_cast<int16*>(stream), len / 4);
SDL_UnlockMutex(fm_mutex);
}
} // namespace
MAKO::MAKO(NACT* parent, const Config& config) :
use_fm(config.use_fm),
current_music(0),
next_loop(0),
nact(parent)
{
int mix_init_flags = MIX_INIT_MID;
if (!config.playlist.empty() && load_playlist(config.playlist.c_str()))
mix_init_flags |= MIX_INIT_MP3 | MIX_INIT_OGG;
strcpy_s(amus, 16, "AMUS.DAT");
strcpy_s(amse, 16, "AMSE.DAT"); // 実際には使わない
for(int i = 1; i <= 99; i++) {
cd_track[i] = 0;
}
if (Mix_Init(mix_init_flags) != mix_init_flags)
WARNING("Mix_Init(0x%x) failed", mix_init_flags);
if (Mix_OpenAudio(SAMPLE_RATE, AUDIO_S16LSB, 2, 4096) < 0)
WARNING("Mix_OpenAudio failed: %s", Mix_GetError());
}
MAKO::~MAKO()
{
stop_pcm();
Mix_CloseAudio();
Mix_Quit();
}
bool MAKO::load_playlist(const char* path)
{
FILE* fp = fopen(path, "r");
if (!fp) {
WARNING("Cannot open %s", path);
return false;
}
char buf[256];
while (fgets(buf, sizeof(buf) - 1, fp)) {
for (char *p = buf; *p; p++) {
if (*p == '\\')
*p = '/';
else if (*p == '\r' || *p == '\n')
*p = '\0';
}
playlist.push_back(buf[0] ? strdup(buf) : NULL);
}
fclose(fp);
return true;
}
void MAKO::play_music(int page)
{
if(current_music == page)
return;
stop_music();
int track = page < 100 ? cd_track[page] : 0;
if(track) {
if (track < playlist.size() && playlist[track]) {
mix_music = Mix_LoadMUS(playlist[track]);
if (!mix_music) {
WARNING("Mix_LoadMUS failed: %s: %s", playlist[track], Mix_GetError());
return;
}
if (Mix_PlayMusic(mix_music, next_loop ? next_loop : -1) != 0) {
WARNING("Mix_PlayMusic failed: %s", Mix_GetError());
Mix_FreeMusic(mix_music);
return;
}
}
} else if (use_fm) {
DRI dri;
int size;
uint8* data = dri.load(amus, page, &size);
if (!data)
return;
if (!fm_mutex)
fm_mutex = SDL_CreateMutex();
SDL_LockMutex(fm_mutex);
fm = std::make_unique<MakoFMgen>(SAMPLE_RATE, data, true);
Mix_HookMusic(&FMHook, this);
SDL_UnlockMutex(fm_mutex);
} else {
auto midi = std::make_unique<MAKOMidi>(nact, amus);
if (midi->load_mml(page)) {
midi->load_mda(page);
smf = midi->generate_smf(next_loop);
SDL_RWops *rwops = SDL_RWFromConstMem(smf.data(), smf.size());
mix_music = Mix_LoadMUSType_RW(rwops, MUS_MID, SDL_TRUE /* freesrc */);
if (!mix_music) {
WARNING("Mix_LoadMUS failed: %s", Mix_GetError());
return;
}
if (Mix_PlayMusic(mix_music, -1) != 0) {
WARNING("Mix_PlayMusic failed: %s", Mix_GetError());
Mix_FreeMusic(mix_music);
return;
}
}
}
current_music = page;
}
void MAKO::stop_music()
{
if (mix_music) {
Mix_FreeMusic(mix_music);
mix_music = NULL;
smf.clear();
}
Mix_HookMusic(NULL, NULL);
current_music = 0;
}
bool MAKO::check_music()
{
return Mix_PlayingMusic();
}
void MAKO::get_mark(int* mark, int* loop)
{
SDL_LockMutex(fm_mutex);
if (fm) {
fm->get_mark(mark, loop);
} else {
*mark = 0;
*loop = 0;
}
SDL_UnlockMutex(fm_mutex);
}
void MAKO::play_pcm(int page, bool loop)
{
static char header[44] = {
'R' , 'I' , 'F' , 'F' , 0x00, 0x00, 0x00, 0x00, 'W' , 'A' , 'V' , 'E' , 'f' , 'm' , 't' , ' ' ,
0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x40, 0x1f, 0x00, 0x00, 0x40, 0x1f, 0x00, 0x00,
0x01, 0x00, 0x08, 0x00, 'd' , 'a' , 't' , 'a' , 0x00, 0x00, 0x00, 0x00
};
stop_pcm();
uint8* buffer = NULL;
int size;
DRI* dri = new DRI();
if((buffer = dri->load("AWAV.DAT", page, &size)) != NULL) {
// WAV形式 (Only You)
mix_chunk = Mix_LoadWAV_RW(SDL_RWFromConstMem(buffer, size), 1 /* freesrc */);
free(buffer);
Mix_PlayChannel(-1, mix_chunk, loop ? -1 : 0);
} else if((buffer = dri->load("AMSE.DAT", page, &size)) != NULL) {
// AMSE形式 (乙女戦記)
int total = (size - 12) * 2 + 0x24;
int samples = (size - 12) * 2;
uint8* wav = (uint8*)malloc(total + 8);
memcpy(wav, header, 44);
wav[ 4] = (total >> 0) & 0xff;
wav[ 5] = (total >> 8) & 0xff;
wav[ 6] = (total >> 16) & 0xff;
wav[ 7] = (total >> 24) & 0xff;
wav[40] = (samples >> 0) & 0xff;
wav[41] = (samples >> 8) & 0xff;
wav[42] = (samples >> 16) & 0xff;
wav[43] = (samples >> 24) & 0xff;
for(int i = 12, p = 44; i < size; i++) {
wav[p++] = buffer[i] & 0xf0;
wav[p++] = (buffer[i] & 0x0f) << 4;
}
free(buffer);
mix_chunk = Mix_LoadWAV_RW(SDL_RWFromConstMem(wav, total + 8), 1 /* freesrc */);
free(wav);
Mix_PlayChannel(-1, mix_chunk, loop ? -1 : 0);
}
}
void MAKO::stop_pcm()
{
Mix_HaltChannel(-1);
if (mix_chunk) {
Mix_FreeChunk(mix_chunk);
mix_chunk = NULL;
}
}
bool MAKO::check_pcm()
{
// 再生中でtrue
return Mix_Playing(-1) != 0;
}
/*
ALICE SOFT SYSTEM 3 for Win32
[ MAKO ]
*/
#include <memory>
#include <SDL.h>
#include <SDL_mixer.h>
#include "mako.h"
#include "mako_midi.h"
#include "fm/mako_fmgen.h"
#include "../config.h"
#include "dri.h"
// MIX_INIT_FLUIDSYNTH was renamed to MIX_INIT_MID in SDL_mixer 2.0.2
#if (SDL_MIXER_MAJOR_VERSION == 2) && (SDL_MIXER_MINOR_VERSION == 0) && (SDL_MIXER_PATCHLEVEL < 2)
#define MIX_INIT_MID MIX_INIT_FLUIDSYNTH
#endif
namespace {
const int SAMPLE_RATE = 44100;
std::vector<uint8> smf;
Mix_Music *mix_music;
Mix_Chunk *mix_chunk;
SDL_mutex* fm_mutex;
std::unique_ptr<MakoFMgen> fm;
void FMHook(void *udata, Uint8 *stream, int len) {
SDL_LockMutex(fm_mutex);
fm->Process(reinterpret_cast<int16*>(stream), len / 4);
SDL_UnlockMutex(fm_mutex);
}
} // namespace
MAKO::MAKO(NACT* parent, const Config& config) :
use_fm(config.use_fm),
current_music(0),
next_loop(0),
nact(parent)
{
int mix_init_flags = MIX_INIT_MID;
if (!config.playlist.empty() && load_playlist(config.playlist.c_str()))
mix_init_flags |= MIX_INIT_MP3 | MIX_INIT_OGG;
strcpy_s(amus, 16, "AMUS.DAT");
strcpy_s(amse, 16, "AMSE.DAT"); // 実際には使わない
for(int i = 1; i <= 99; i++) {
cd_track[i] = 0;
}
if (Mix_Init(mix_init_flags) != mix_init_flags)
WARNING("Mix_Init(0x%x) failed", mix_init_flags);
if (Mix_OpenAudio(SAMPLE_RATE, AUDIO_S16LSB, 2, 4096) < 0)
WARNING("Mix_OpenAudio failed: %s", Mix_GetError());
}
MAKO::~MAKO()
{
stop_pcm();
Mix_CloseAudio();
Mix_Quit();
}
bool MAKO::load_playlist(const char* path)
{
FILE* fp = fopen(path, "r");
if (!fp) {
WARNING("Cannot open %s", path);
return false;
}
char buf[256];
while (fgets(buf, sizeof(buf) - 1, fp)) {
for (char *p = buf; *p; p++) {
if (*p == '\\')
*p = '/';
else if (*p == '\r' || *p == '\n')
*p = '\0';
}
playlist.push_back(buf[0] ? strdup(buf) : NULL);
}
fclose(fp);
return true;
}
void MAKO::play_music(int page)
{
if(current_music == page)
return;
stop_music();
int track = page < 100 ? cd_track[page] : 0;
if(track) {
if (track < playlist.size() && playlist[track]) {
mix_music = Mix_LoadMUS(playlist[track]);
if (!mix_music) {
WARNING("Mix_LoadMUS failed: %s: %s", playlist[track], Mix_GetError());
return;
}
if (Mix_PlayMusic(mix_music, next_loop ? next_loop : -1) != 0) {
WARNING("Mix_PlayMusic failed: %s", Mix_GetError());
Mix_FreeMusic(mix_music);
return;
}
}
} else if (use_fm) {
DRI dri;
int size;
uint8* data = dri.load(amus, page, &size);
if (!data)
return;
if (!fm_mutex)
fm_mutex = SDL_CreateMutex();
SDL_LockMutex(fm_mutex);
fm = std::make_unique<MakoFMgen>(SAMPLE_RATE, data, true);
Mix_HookMusic(&FMHook, this);
SDL_UnlockMutex(fm_mutex);
} else {
auto midi = std::make_unique<MAKOMidi>(nact, amus);
if (midi->load_mml(page)) {
midi->load_mda(page);
smf = midi->generate_smf(next_loop);
SDL_RWops *rwops = SDL_RWFromConstMem(smf.data(), smf.size());
mix_music = Mix_LoadMUSType_RW(rwops, MUS_MID, SDL_TRUE /* freesrc */);
if (!mix_music) {
WARNING("Mix_LoadMUS failed: %s", Mix_GetError());
return;
}
if (Mix_PlayMusic(mix_music, -1) != 0) {
WARNING("Mix_PlayMusic failed: %s", Mix_GetError());
Mix_FreeMusic(mix_music);
return;
}
}
}
current_music = page;
}
void MAKO::stop_music()
{
if (mix_music) {
Mix_FreeMusic(mix_music);
mix_music = NULL;
smf.clear();
}
Mix_HookMusic(NULL, NULL);
current_music = 0;
}
bool MAKO::check_music()
{
return Mix_PlayingMusic();
}
void MAKO::get_mark(int* mark, int* loop)
{
SDL_LockMutex(fm_mutex);
if (fm) {
fm->get_mark(mark, loop);
} else {
*mark = 0;
*loop = 0;
}
SDL_UnlockMutex(fm_mutex);
}
void MAKO::play_pcm(int page, bool loop)
{
static char header[44] = {
'R' , 'I' , 'F' , 'F' , 0x00, 0x00, 0x00, 0x00, 'W' , 'A' , 'V' , 'E' , 'f' , 'm' , 't' , ' ' ,
0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x40, 0x1f, 0x00, 0x00, 0x40, 0x1f, 0x00, 0x00,
0x01, 0x00, 0x08, 0x00, 'd' , 'a' , 't' , 'a' , 0x00, 0x00, 0x00, 0x00
};
stop_pcm();
uint8* buffer = NULL;
int size;
DRI* dri = new DRI();
if((buffer = dri->load("AWAV.DAT", page, &size)) != NULL) {
// WAV形式 (Only You)
mix_chunk = Mix_LoadWAV_RW(SDL_RWFromConstMem(buffer, size), 1 /* freesrc */);
free(buffer);
Mix_PlayChannel(-1, mix_chunk, loop ? -1 : 0);
} else if((buffer = dri->load("AMSE.DAT", page, &size)) != NULL) {
// AMSE形式 (乙女戦記)
int total = (size - 12) * 2 + 0x24;
int samples = (size - 12) * 2;
uint8* wav = (uint8*)malloc(total + 8);
memcpy(wav, header, 44);
wav[ 4] = (total >> 0) & 0xff;
wav[ 5] = (total >> 8) & 0xff;
wav[ 6] = (total >> 16) & 0xff;
wav[ 7] = (total >> 24) & 0xff;
wav[40] = (samples >> 0) & 0xff;
wav[41] = (samples >> 8) & 0xff;
wav[42] = (samples >> 16) & 0xff;
wav[43] = (samples >> 24) & 0xff;
for(int i = 12, p = 44; i < size; i++) {
wav[p++] = buffer[i] & 0xf0;
wav[p++] = (buffer[i] & 0x0f) << 4;
}
free(buffer);
mix_chunk = Mix_LoadWAV_RW(SDL_RWFromConstMem(wav, total + 8), 1 /* freesrc */);
free(wav);
Mix_PlayChannel(-1, mix_chunk, loop ? -1 : 0);
}
}
void MAKO::stop_pcm()
{
Mix_HaltChannel(-1);
if (mix_chunk) {
Mix_FreeChunk(mix_chunk);
mix_chunk = NULL;
}
}
bool MAKO::check_pcm()
{
// 再生中でtrue
return Mix_Playing(-1) != 0;
}
+38 -38
View File
@@ -1,38 +1,38 @@
#ifdef _WIN32
#include <windows.h>
#undef ERROR
#endif
#include "common.h"
SDL_RWops* open_resource(const char* name, const char* type) {
#ifdef _WIN32
// On Windows, read from resource.
HINSTANCE hInst = GetModuleHandle(NULL);
HRSRC hRes = FindResource(hInst, name, type);
HGLOBAL hGlobal = LoadResource(hInst, hRes);
if (!hGlobal) {
WARNING("Cannot load resource %s (type: %s)", name, type);
return NULL;
}
return SDL_RWFromConstMem(LockResource(hGlobal), SizeofResource(hInst, hRes));
#else
// On Android, read from APK assets.
// On other platforms, read from a file under RESOURCE_PATH.
char path[_MAX_PATH];
sprintf_s(path, _MAX_PATH, "%s%s/%s", RESOURCE_PATH, type, name);
return SDL_RWFromFile(path, "rb");
#endif
}
SDL_RWops* open_file(const char* name) {
#ifdef __ANDROID__
// We cannot use SDL_RWFromFile() because it does not resolve relative
// paths using the current directory on Android.
FILE *fp = fopen(name, "rb");
if (!fp)
return NULL;
return SDL_RWFromFP(fp, SDL_TRUE);
#else
return SDL_RWFromFile(name, "rb");
#endif
}
#ifdef _WIN32
#include <windows.h>
#undef ERROR
#endif
#include "common.h"
SDL_RWops* open_resource(const char* name, const char* type) {
#ifdef _WIN32
// On Windows, read from resource.
HINSTANCE hInst = GetModuleHandle(NULL);
HRSRC hRes = FindResource(hInst, name, type);
HGLOBAL hGlobal = LoadResource(hInst, hRes);
if (!hGlobal) {
WARNING("Cannot load resource %s (type: %s)", name, type);
return NULL;
}
return SDL_RWFromConstMem(LockResource(hGlobal), SizeofResource(hInst, hRes));
#else
// On Android, read from APK assets.
// On other platforms, read from a file under RESOURCE_PATH.
char path[_MAX_PATH];
sprintf_s(path, _MAX_PATH, "%s%s/%s", RESOURCE_PATH, type, name);
return SDL_RWFromFile(path, "rb");
#endif
}
SDL_RWops* open_file(const char* name) {
#ifdef __ANDROID__
// We cannot use SDL_RWFromFile() because it does not resolve relative
// paths using the current directory on Android.
FILE *fp = fopen(name, "rb");
if (!fp)
return NULL;
return SDL_RWFromFP(fp, SDL_TRUE);
#else
return SDL_RWFromFile(name, "rb");
#endif
}
+533 -533
View File
File diff suppressed because it is too large Load Diff
+220 -220
View File
@@ -1,220 +1,220 @@
/*
ALICE SOFT SYSTEM 3 for Win32
[ AGS ]
*/
#ifndef _AGS_H_
#define _AGS_H_
#include <stdio.h>
#include "../common.h"
#include "nact.h"
#include <SDL_ttf.h>
#define MAX_CG 10000
static inline uint32 SETPALETTE256(uint32 R, uint32 G, uint32 B)
{
return ((R & 0xff) << 16) | ((G & 0xff) << 8) | (B & 0xff);
}
static inline uint32 SETPALETTE16(uint32 R, uint32 G, uint32 B)
{
R = (255 * (R & 0x0f)) / 15;
G = (255 * (G & 0x0f)) / 15;
B = (255 * (B & 0x0f)) / 15;
return SETPALETTE256(R, G, B);
}
inline uint32* surface_line(SDL_Surface* surface, int y)
{
return (uint32*)((uint8*)surface->pixels + surface->pitch * y);
}
struct Config;
class AGS
{
protected:
NACT* nact;
private:
SDL_Renderer* sdlRenderer;
SDL_Texture* sdlTexture;
// Surface
SDL_Surface* hBmpScreen[3]; // 8bpp * 3 (表, 裏, メニュー)
SDL_Surface* hBmpDest; // DIBSection 24bpp (最終出力先)
// フォント
SDL_RWops* rw_font;
TTF_Font* hFont16;
TTF_Font* hFont24;
TTF_Font* hFont32;
TTF_Font* hFont48;
TTF_Font* hFont64;
// カーソル
SDL_Cursor* hCursor[10];
// AGS
void load_gm3(uint8* data, int page, int transparent); // Intruder -桜屋敷の探索-
void load_vsp2l(uint8* data, int page, int transparent); // Little Vampire
void load_gl3(uint8* data, int page, int transparent);
void load_pms(uint8* data, int page, int transparent);
void load_bmp(const char* file_name); // あゆみちゃん物語 フルカラー実写版
void load_vsp(uint8* data, int page, int transparent);
void draw_char(int dest, int dest_x, int dest_y, uint16 code, TTF_Font* font, uint8 color);
void draw_char_antialias(int dest, int dest_x, int dest_y, uint16 code, TTF_Font* font, uint8 color, uint8 cache[]);
void draw_gaiji(int dest, int dest_x, int dest_y, uint16 code, int size, uint8 color);
void draw_window(int sx, int sy, int ex, int ey, bool frame, uint8 frame_color, uint8 back_color);
void draw_screen(int sx, int sy, int width, int heignt);
void invalidate_screen(int sx, int sy, int width, int height);
uint8 palR(uint8 col) { return screen_palette[col] >> 16 & 0xff; }
uint8 palG(uint8 col) { return screen_palette[col] >> 8 & 0xff; }
uint8 palB(uint8 col) { return screen_palette[col] & 0xff; }
int nearest_color(int r, int g, int b);
uint32* vram[3][480]; // 仮想VRAMへのポインタ
uint32 program_palette[256];
uint32 screen_palette[256];
uint8 gaiji[188][32];
int fade_level = 0; // 0-255
int fade_color = 0; // 0: black, 255: white
public:
AGS(NACT* parent, const Config& config);
~AGS();
void update_screen();
void flush_screen(bool update);
void load_cg(int page, int transparent);
void set_palette(int index, int r, int g, int b);
uint8 get_pixel(int dest, int x, int y);
void set_pixel(int dest, int x, int y, uint8 color);
void fade_out(int duration_ms, bool white);
void fade_in(int duration_ms);
void copy(int sx, int sy, int ex, int ey, int dx, int dy);
void gcopy(int gsc, int gde, int glx, int gly, int gsw);
void paint(int x, int y, uint8 color);
void draw_box(int index);
void draw_mesh(int sx, int sy, int width, int height);
void box_fill(int dest, int sx, int sy, int ex, int ey, uint8 color);
void box_line(int dest, int sx, int sy, int ex, int ey, uint8 color);
void draw_text(const char* string, bool text_wait = false);
void clear_text_window(int index, bool erase);
bool return_text_line(int index);
void draw_push(int index);
void open_text_window(int index, bool erase);
void close_text_window(int index, bool update);
void clear_menu_window();
void open_menu_window(int index);
void redraw_menu_window(int index, int selected);
void close_menu_window(int index);
void load_cursor(int page);
void select_cursor();
void translate_mouse_coords(int* x, int* y);
void save_screenshot(const char* path);
bool dirty;
// ACG.DAT
char acg[16];
// 画面選択
int src_screen;
int dest_screen;
int scroll;
int screen_height;
// メッセージ表示
int text_dest_x;
int text_dest_y;
int text_space;
int text_font_size;
uint8 text_font_color;
uint8 text_frame_color;
uint8 text_back_color;
int text_font_maxsize; // その行での最大フォントサイズ
// メニュー表示
int menu_dest_x;
int menu_dest_y;
int menu_font_size;
uint8 menu_font_color;
uint8 menu_frame_color;
uint8 menu_back_color;
bool menu_fix;
bool draw_hankaku;
bool draw_menu;
// ウィンドウ (Bコマンド)
typedef struct {
int sx;
int sy;
int ex;
int ey;
bool frame;
bool push;
uint32* screen;
int screen_x;
int screen_y;
int screen_width;
int screen_height;
uint32 screen_palette[256];
uint32* window;
int window_x;
int window_y;
int window_width;
int window_height;
uint32 window_palette[256];
} WINDOW;
WINDOW menu_w[10];
WINDOW text_w[10];
// ボックス (E, Y7コマンド)
typedef struct {
uint8 color;
int sx;
int sy;
int ex;
int ey;
} BOX;
BOX box[20];
// CG表示
bool set_cg_dest;
int cg_dest_x;
int cg_dest_y;
bool get_palette;
bool extract_palette;
bool extract_cg;
bool extract_palette_cg[MAX_CG];
int palette_bank;
// マウスカーソル
uint8 cursor_color;
int cursor_index;
};
extern "C" void ags_setAntialiasedStringMode(int on);
#endif
/*
ALICE SOFT SYSTEM 3 for Win32
[ AGS ]
*/
#ifndef _AGS_H_
#define _AGS_H_
#include <stdio.h>
#include "../common.h"
#include "nact.h"
#include <SDL_ttf.h>
#define MAX_CG 10000
static inline uint32 SETPALETTE256(uint32 R, uint32 G, uint32 B)
{
return ((R & 0xff) << 16) | ((G & 0xff) << 8) | (B & 0xff);
}
static inline uint32 SETPALETTE16(uint32 R, uint32 G, uint32 B)
{
R = (255 * (R & 0x0f)) / 15;
G = (255 * (G & 0x0f)) / 15;
B = (255 * (B & 0x0f)) / 15;
return SETPALETTE256(R, G, B);
}
inline uint32* surface_line(SDL_Surface* surface, int y)
{
return (uint32*)((uint8*)surface->pixels + surface->pitch * y);
}
struct Config;
class AGS
{
protected:
NACT* nact;
private:
SDL_Renderer* sdlRenderer;
SDL_Texture* sdlTexture;
// Surface
SDL_Surface* hBmpScreen[3]; // 8bpp * 3 (表, 裏, メニュー)
SDL_Surface* hBmpDest; // DIBSection 24bpp (最終出力先)
// フォント
SDL_RWops* rw_font;
TTF_Font* hFont16;
TTF_Font* hFont24;
TTF_Font* hFont32;
TTF_Font* hFont48;
TTF_Font* hFont64;
// カーソル
SDL_Cursor* hCursor[10];
// AGS
void load_gm3(uint8* data, int page, int transparent); // Intruder -桜屋敷の探索-
void load_vsp2l(uint8* data, int page, int transparent); // Little Vampire
void load_gl3(uint8* data, int page, int transparent);
void load_pms(uint8* data, int page, int transparent);
void load_bmp(const char* file_name); // あゆみちゃん物語 フルカラー実写版
void load_vsp(uint8* data, int page, int transparent);
void draw_char(int dest, int dest_x, int dest_y, uint16 code, TTF_Font* font, uint8 color);
void draw_char_antialias(int dest, int dest_x, int dest_y, uint16 code, TTF_Font* font, uint8 color, uint8 cache[]);
void draw_gaiji(int dest, int dest_x, int dest_y, uint16 code, int size, uint8 color);
void draw_window(int sx, int sy, int ex, int ey, bool frame, uint8 frame_color, uint8 back_color);
void draw_screen(int sx, int sy, int width, int heignt);
void invalidate_screen(int sx, int sy, int width, int height);
uint8 palR(uint8 col) { return screen_palette[col] >> 16 & 0xff; }
uint8 palG(uint8 col) { return screen_palette[col] >> 8 & 0xff; }
uint8 palB(uint8 col) { return screen_palette[col] & 0xff; }
int nearest_color(int r, int g, int b);
uint32* vram[3][480]; // 仮想VRAMへのポインタ
uint32 program_palette[256];
uint32 screen_palette[256];
uint8 gaiji[188][32];
int fade_level = 0; // 0-255
int fade_color = 0; // 0: black, 255: white
public:
AGS(NACT* parent, const Config& config);
~AGS();
void update_screen();
void flush_screen(bool update);
void load_cg(int page, int transparent);
void set_palette(int index, int r, int g, int b);
uint8 get_pixel(int dest, int x, int y);
void set_pixel(int dest, int x, int y, uint8 color);
void fade_out(int duration_ms, bool white);
void fade_in(int duration_ms);
void copy(int sx, int sy, int ex, int ey, int dx, int dy);
void gcopy(int gsc, int gde, int glx, int gly, int gsw);
void paint(int x, int y, uint8 color);
void draw_box(int index);
void draw_mesh(int sx, int sy, int width, int height);
void box_fill(int dest, int sx, int sy, int ex, int ey, uint8 color);
void box_line(int dest, int sx, int sy, int ex, int ey, uint8 color);
void draw_text(const char* string, bool text_wait = false);
void clear_text_window(int index, bool erase);
bool return_text_line(int index);
void draw_push(int index);
void open_text_window(int index, bool erase);
void close_text_window(int index, bool update);
void clear_menu_window();
void open_menu_window(int index);
void redraw_menu_window(int index, int selected);
void close_menu_window(int index);
void load_cursor(int page);
void select_cursor();
void translate_mouse_coords(int* x, int* y);
void save_screenshot(const char* path);
bool dirty;
// ACG.DAT
char acg[16];
// 画面選択
int src_screen;
int dest_screen;
int scroll;
int screen_height;
// メッセージ表示
int text_dest_x;
int text_dest_y;
int text_space;
int text_font_size;
uint8 text_font_color;
uint8 text_frame_color;
uint8 text_back_color;
int text_font_maxsize; // その行での最大フォントサイズ
// メニュー表示
int menu_dest_x;
int menu_dest_y;
int menu_font_size;
uint8 menu_font_color;
uint8 menu_frame_color;
uint8 menu_back_color;
bool menu_fix;
bool draw_hankaku;
bool draw_menu;
// ウィンドウ (Bコマンド)
typedef struct {
int sx;
int sy;
int ex;
int ey;
bool frame;
bool push;
uint32* screen;
int screen_x;
int screen_y;
int screen_width;
int screen_height;
uint32 screen_palette[256];
uint32* window;
int window_x;
int window_y;
int window_width;
int window_height;
uint32 window_palette[256];
} WINDOW;
WINDOW menu_w[10];
WINDOW text_w[10];
// ボックス (E, Y7コマンド)
typedef struct {
uint8 color;
int sx;
int sy;
int ex;
int ey;
} BOX;
BOX box[20];
// CG表示
bool set_cg_dest;
int cg_dest_x;
int cg_dest_y;
bool get_palette;
bool extract_palette;
bool extract_cg;
bool extract_palette_cg[MAX_CG];
int palette_bank;
// マウスカーソル
uint8 cursor_color;
int cursor_index;
};
extern "C" void ags_setAntialiasedStringMode(int on);
#endif
+46 -46
View File
@@ -1,46 +1,46 @@
/*
ALICE SOFT SYSTEM 3 for Win32
[ AGS - bmp loader ]
*/
#include "ags.h"
#include "../fileio.h"
void AGS::load_bmp(const char* file_name)
{
// ヘッダ取得
int sx = 0, sy = 0;
// Jコマンドの処理
if(set_cg_dest) {
sx = cg_dest_x;
sy = cg_dest_y;
set_cg_dest = false;
}
if(extract_cg) {
assert(false);
#if 0
// BMP読み込み
WCHAR wszFilePath[_MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, FILEIO::GetFilePath(file_name), -1, wszFilePath, _MAX_PATH);
Gdiplus::Bitmap *pBitmap = Gdiplus::Bitmap::FromFile(wszFilePath);
for(unsigned int y = 0; y < pBitmap->GetHeight(); y++) {
for(unsigned int x = 0; x < pBitmap->GetWidth(); x++) {
Gdiplus::Color srcColor;
pBitmap->GetPixel(x, y, &srcColor);
vram[dest_screen][y + sy][sx + x] = SETPALETTE256(srcColor.GetR(), srcColor.GetG(), srcColor.GetB()) | 0x80000000;
}
}
// 画面更新
if(dest_screen == 0) {
draw_screen(sx, sy, pBitmap->GetWidth(), pBitmap->GetHeight());
}
// BMP開放
delete pBitmap;
#endif
}
}
/*
ALICE SOFT SYSTEM 3 for Win32
[ AGS - bmp loader ]
*/
#include "ags.h"
#include "../fileio.h"
void AGS::load_bmp(const char* file_name)
{
// ヘッダ取得
int sx = 0, sy = 0;
// Jコマンドの処理
if(set_cg_dest) {
sx = cg_dest_x;
sy = cg_dest_y;
set_cg_dest = false;
}
if(extract_cg) {
assert(false);
#if 0
// BMP読み込み
WCHAR wszFilePath[_MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, FILEIO::GetFilePath(file_name), -1, wszFilePath, _MAX_PATH);
Gdiplus::Bitmap *pBitmap = Gdiplus::Bitmap::FromFile(wszFilePath);
for(unsigned int y = 0; y < pBitmap->GetHeight(); y++) {
for(unsigned int x = 0; x < pBitmap->GetWidth(); x++) {
Gdiplus::Color srcColor;
pBitmap->GetPixel(x, y, &srcColor);
vram[dest_screen][y + sy][sx + x] = SETPALETTE256(srcColor.GetR(), srcColor.GetG(), srcColor.GetB()) | 0x80000000;
}
}
// 画面更新
if(dest_screen == 0) {
draw_screen(sx, sy, pBitmap->GetWidth(), pBitmap->GetHeight());
}
// BMP開放
delete pBitmap;
#endif
}
}
+121 -121
View File
@@ -1,121 +1,121 @@
/*
ALICE SOFT SYSTEM 3 for Win32
[ AGS - draw ]
*/
#include "ags.h"
#include <string.h>
extern SDL_Window* g_window;
void AGS::load_cursor(int page)
{
// カーソルCGをロードする
bool j_set = set_cg_dest;
int j_x = cg_dest_x;
int j_y = cg_dest_y;
int dest = dest_screen;
set_cg_dest = true;
cg_dest_x = 0;
cg_dest_y = 0;
dest_screen = 1;
load_cg(page, -1);
set_cg_dest = j_set;
cg_dest_x = j_x;
cg_dest_y = j_y;
dest_screen = dest;
// フォントの生成
for(int i = 0; i < 10; i++) {
// パターン読み込み
uint8 pat[34][34];
memset(pat, 0, sizeof(pat));
for(int y = 0; y < 32; y++) {
for(int x = 0; x < 32; x++) {
pat[y + 1][x + 1] = (vram[1][y >> 1][(x >> 1) + 16 * i] & 0xf) ? 1 : 0;
}
}
// パターン縁取り
for(int y = 1; y <= 32; y++) {
for(int x = 1; x <= 32; x++) {
if(pat[y][x] == 0 && (pat[y - 1][x] == 1 || pat[y + 1][x] == 1 || pat[y][x - 1] == 1 || pat[y][x + 1] == 1)) {
pat[y][x] = 2;
}
}
}
// フォント生成
uint8 amask[128], xmask[128];
memset(amask, 0, sizeof(amask));
memset(xmask, 0, sizeof(xmask));
for(int y = 0; y < 32; y++) {
for(int x = 0; x < 32; x += 8) {
amask[y * 4 + (x >> 3)] = (pat[y + 1][x + 1] == 0) ? 0x80 : 0;
amask[y * 4 + (x >> 3)] |= (pat[y + 1][x + 2] == 0) ? 0x40 : 0;
amask[y * 4 + (x >> 3)] |= (pat[y + 1][x + 3] == 0) ? 0x20 : 0;
amask[y * 4 + (x >> 3)] |= (pat[y + 1][x + 4] == 0) ? 0x10 : 0;
amask[y * 4 + (x >> 3)] |= (pat[y + 1][x + 5] == 0) ? 0x08 : 0;
amask[y * 4 + (x >> 3)] |= (pat[y + 1][x + 6] == 0) ? 0x04 : 0;
amask[y * 4 + (x >> 3)] |= (pat[y + 1][x + 7] == 0) ? 0x02 : 0;
amask[y * 4 + (x >> 3)] |= (pat[y + 1][x + 8] == 0) ? 0x01 : 0;
xmask[y * 4 + (x >> 3)] = (pat[y + 1][x + 1] == 1) ? 0x80 : 0;
xmask[y * 4 + (x >> 3)] |= (pat[y + 1][x + 2] == 1) ? 0x40 : 0;
xmask[y * 4 + (x >> 3)] |= (pat[y + 1][x + 3] == 1) ? 0x20 : 0;
xmask[y * 4 + (x >> 3)] |= (pat[y + 1][x + 4] == 1) ? 0x10 : 0;
xmask[y * 4 + (x >> 3)] |= (pat[y + 1][x + 5] == 1) ? 0x08 : 0;
xmask[y * 4 + (x >> 3)] |= (pat[y + 1][x + 6] == 1) ? 0x04 : 0;
xmask[y * 4 + (x >> 3)] |= (pat[y + 1][x + 7] == 1) ? 0x02 : 0;
xmask[y * 4 + (x >> 3)] |= (pat[y + 1][x + 8] == 1) ? 0x01 : 0;
}
}
if(hCursor[i]) {
SDL_FreeCursor(hCursor[i]);
}
// TODO: fix amask/xmask values
hCursor[i] = SDL_CreateCursor(amask, xmask, 32, 32, 2, 2);
}
}
void AGS::select_cursor()
{
if(cursor_index == 0) {
SDL_SetCursor(SDL_GetDefaultCursor());
} else if(1 <= cursor_index && cursor_index <= 10 && hCursor[cursor_index - 1]) {
SDL_SetCursor(hCursor[cursor_index - 1]);
}
}
void AGS::translate_mouse_coords(int* x, int* y)
{
// scale mouse x and y
float scalex, scaley;
SDL_RenderGetScale(sdlRenderer, &scalex, &scaley);
*x *= scalex;
*y *= scaley;
// calculate window borders
int logw, logh;
SDL_RenderGetLogicalSize(sdlRenderer, &logw, &logh);
float scalew, scaleh;
scalew = logw * scalex;
scaleh = logh * scaley;
int winw, winh;
SDL_GetWindowSize(g_window, &winw, &winh);
float border_left = (winw - scalew) / 2;
float border_top = (winh - scaleh) / 2;
// offset x and y by window borders
*x += border_left;
*y += border_top;
}
/*
ALICE SOFT SYSTEM 3 for Win32
[ AGS - draw ]
*/
#include "ags.h"
#include <string.h>
extern SDL_Window* g_window;
void AGS::load_cursor(int page)
{
// カーソルCGをロードする
bool j_set = set_cg_dest;
int j_x = cg_dest_x;
int j_y = cg_dest_y;
int dest = dest_screen;
set_cg_dest = true;
cg_dest_x = 0;
cg_dest_y = 0;
dest_screen = 1;
load_cg(page, -1);
set_cg_dest = j_set;
cg_dest_x = j_x;
cg_dest_y = j_y;
dest_screen = dest;
// フォントの生成
for(int i = 0; i < 10; i++) {
// パターン読み込み
uint8 pat[34][34];
memset(pat, 0, sizeof(pat));
for(int y = 0; y < 32; y++) {
for(int x = 0; x < 32; x++) {
pat[y + 1][x + 1] = (vram[1][y >> 1][(x >> 1) + 16 * i] & 0xf) ? 1 : 0;
}
}
// パターン縁取り
for(int y = 1; y <= 32; y++) {
for(int x = 1; x <= 32; x++) {
if(pat[y][x] == 0 && (pat[y - 1][x] == 1 || pat[y + 1][x] == 1 || pat[y][x - 1] == 1 || pat[y][x + 1] == 1)) {
pat[y][x] = 2;
}
}
}
// フォント生成
uint8 amask[128], xmask[128];
memset(amask, 0, sizeof(amask));
memset(xmask, 0, sizeof(xmask));
for(int y = 0; y < 32; y++) {
for(int x = 0; x < 32; x += 8) {
amask[y * 4 + (x >> 3)] = (pat[y + 1][x + 1] == 0) ? 0x80 : 0;
amask[y * 4 + (x >> 3)] |= (pat[y + 1][x + 2] == 0) ? 0x40 : 0;
amask[y * 4 + (x >> 3)] |= (pat[y + 1][x + 3] == 0) ? 0x20 : 0;
amask[y * 4 + (x >> 3)] |= (pat[y + 1][x + 4] == 0) ? 0x10 : 0;
amask[y * 4 + (x >> 3)] |= (pat[y + 1][x + 5] == 0) ? 0x08 : 0;
amask[y * 4 + (x >> 3)] |= (pat[y + 1][x + 6] == 0) ? 0x04 : 0;
amask[y * 4 + (x >> 3)] |= (pat[y + 1][x + 7] == 0) ? 0x02 : 0;
amask[y * 4 + (x >> 3)] |= (pat[y + 1][x + 8] == 0) ? 0x01 : 0;
xmask[y * 4 + (x >> 3)] = (pat[y + 1][x + 1] == 1) ? 0x80 : 0;
xmask[y * 4 + (x >> 3)] |= (pat[y + 1][x + 2] == 1) ? 0x40 : 0;
xmask[y * 4 + (x >> 3)] |= (pat[y + 1][x + 3] == 1) ? 0x20 : 0;
xmask[y * 4 + (x >> 3)] |= (pat[y + 1][x + 4] == 1) ? 0x10 : 0;
xmask[y * 4 + (x >> 3)] |= (pat[y + 1][x + 5] == 1) ? 0x08 : 0;
xmask[y * 4 + (x >> 3)] |= (pat[y + 1][x + 6] == 1) ? 0x04 : 0;
xmask[y * 4 + (x >> 3)] |= (pat[y + 1][x + 7] == 1) ? 0x02 : 0;
xmask[y * 4 + (x >> 3)] |= (pat[y + 1][x + 8] == 1) ? 0x01 : 0;
}
}
if(hCursor[i]) {
SDL_FreeCursor(hCursor[i]);
}
// TODO: fix amask/xmask values
hCursor[i] = SDL_CreateCursor(amask, xmask, 32, 32, 2, 2);
}
}
void AGS::select_cursor()
{
if(cursor_index == 0) {
SDL_SetCursor(SDL_GetDefaultCursor());
} else if(1 <= cursor_index && cursor_index <= 10 && hCursor[cursor_index - 1]) {
SDL_SetCursor(hCursor[cursor_index - 1]);
}
}
void AGS::translate_mouse_coords(int* x, int* y)
{
// scale mouse x and y
float scalex, scaley;
SDL_RenderGetScale(sdlRenderer, &scalex, &scaley);
*x *= scalex;
*y *= scaley;
// calculate window borders
int logw, logh;
SDL_RenderGetLogicalSize(sdlRenderer, &logw, &logh);
float scalew, scaleh;
scalew = logw * scalex;
scaleh = logh * scaley;
int winw, winh;
SDL_GetWindowSize(g_window, &winw, &winh);
float border_left = (winw - scalew) / 2;
float border_top = (winh - scaleh) / 2;
// offset x and y by window borders
*x += border_left;
*y += border_top;
}
+254 -254
View File
@@ -1,254 +1,254 @@
/*
ALICE SOFT SYSTEM 3 for Win32
[ AGS - draw ]
*/
#include "ags.h"
#include <tuple>
#include <utility>
#include <vector>
#include <string.h>
#include "dri.h"
#include "crc32.h"
void AGS::load_cg(int page, int transparent)
{
if (nact->sys_ver == 3) {
// あゆみちゃん物語 フルカラー実写版
if(strncmp(acg, "CGA000.BMP", 10) == 0) {
char file_name[16];
sprintf(file_name, "CGA%03d.BMP", page);
load_bmp(file_name);
return;
} else if(strncmp(acg, "CGB000.BMP", 10) == 0) {
char file_name[16];
sprintf(file_name, "CGB%03d.BMP", page);
load_bmp(file_name);
return;
}
}
DRI* dri = new DRI();
int size;
uint8* data = dri->load(acg, page, &size);
if(data && size > 0) {
switch (nact->sys_ver) {
case 1:
switch (nact->crc32_a) {
case CRC32_BUNKASAI:
load_vsp(data, page, transparent);
break;
case CRC32_INTRUDER:
// load_gm3(data, page, transparent);
load_vsp(data, page, transparent); // 暫定
break;
case CRC32_VAMPIRE:
case CRC32_VAMPIRE_ENG:
load_vsp2l(data, page, transparent);
break;
default:
load_gl3(data, page, transparent);
break;
}
break;
case 2:
if(nact->crc32_a == CRC32_AYUMI_PROTO) {
// あゆみちゃん物語 PROTO
load_gl3(data, page, transparent);
} else if(nact->crc32_a == CRC32_AYUMI_FD || nact->crc32_a == CRC32_AYUMI_HINT) {
// あゆみちゃん物語
load_vsp(data, page, transparent);
} else if(nact->crc32_a == CRC32_SDPS) {
// Super D.P.S
load_pms(data, page, transparent);
} else {
if(data[0x8] == 0) {
load_vsp(data, page, transparent);
} else {
load_pms(data, page, transparent);
}
}
break;
case 3:
if(data[0x8] == 0) {
load_vsp(data, page, transparent);
} else {
load_pms(data, page, transparent);
}
break;
}
}
if (data)
free(data);
delete dri;
}
void AGS::copy(int sx, int sy, int ex, int ey, int dx, int dy)
{
#if 0
int width = ex - sx + 1;
int height = ey - sy + 1;
uint32 tmp[640 * 480];
memcpy(tmp, lpBmpScreen[src_screen], sizeof(tmp));
for(int y = 0; y < height && y + sy < 480 && y + dy < 480; y++) {
uint32* src = &tmp[640 * (479 - (y + sy))];
uint32* dest = vram[dest_screen][y + dy];
for(int x = 0; x < width && x + sx < 640 && x + dx < 640; x++) {
dest[x + dx] = src[x + sx];
}
}
if(dest_screen == 0) {
draw_screen(dx, dy, width, height);
}
#else
int width = ex - sx + 1;
int height = ey - sy + 1;
SDL_Rect srcrect = {sx, sy, width, height};
SDL_Rect destrect = {dx, dy, width, height};
SDL_UnlockSurface(hBmpScreen[src_screen]);
if (src_screen != dest_screen)
SDL_UnlockSurface(hBmpScreen[dest_screen]);
SDL_BlitSurface(hBmpScreen[src_screen], &srcrect, hBmpScreen[dest_screen], &destrect);
if (src_screen != dest_screen)
SDL_LockSurface(hBmpScreen[dest_screen]);
SDL_LockSurface(hBmpScreen[src_screen]);
if(dest_screen == 0) {
draw_screen(dx, dy, ex - sx + 1, ey - sy + 1);
}
#endif
}
void AGS::gcopy(int gsc, int gde, int glx, int gly, int gsw)
{
// N88-BASIC時代のコピーコマンド
int src = (gsw == 0 || gsw == 2) ? 0 : 1;
int dest = (gsw == 0 || gsw == 3) ? 0 : 1;
int sx = (gsc % 80) * 8;
int sy = gsc / 80;
int dx = (gde % 80) * 8;
int dy = gde / 80;
SDL_Rect srcrect = {sx, sy, glx * 8, gly};
SDL_Rect destrect = {dx, dy, glx * 8, gly};
SDL_UnlockSurface(hBmpScreen[src]);
if (src_screen != dest_screen)
SDL_UnlockSurface(hBmpScreen[dest]);
SDL_BlitSurface(hBmpScreen[src], &srcrect, hBmpScreen[dest], &destrect);
if (src_screen != dest_screen)
SDL_LockSurface(hBmpScreen[dest]);
SDL_LockSurface(hBmpScreen[src]);
if(dest == 0) {
draw_screen(dx, dy, glx * 8, gly);
}
}
void AGS::paint(int x, int y, uint8 color)
{
int old_color = vram[0][y][x];
if (old_color == color)
return;
int minx = x, maxx = x, miny = y, maxy = y;
std::vector<std::pair<int, int>> stack;
stack.push_back({x, y});
while (!stack.empty()) {
std::tie(x, y) = stack.back();
stack.pop_back();
while (x >= 0 && vram[0][y][x] == old_color) x--;
x++;
minx = std::min(x, minx);
bool span_above = false, span_below = false;
for (; x < 640 && vram[0][y][x] == old_color; x++) {
vram[0][y][x] = color;
if (y > 0) {
if (!span_above && vram[0][y - 1][x] == old_color) {
stack.push_back({x, y - 1});
span_above = true;
} else if (span_above && vram[0][y - 1][x] != old_color) {
span_above = false;
}
}
if (y < screen_height - 1) {
if (!span_below && vram[0][y + 1][x] == old_color) {
stack.push_back({x, y + 1});
span_below = true;
} else if (span_below && vram[0][y + 1][x] != old_color) {
span_below = false;
}
}
}
maxx = std::max(x - 1, maxx);
miny = std::min(y, miny);
maxy = std::max(y, maxy);
}
draw_screen(minx, miny, maxx - minx + 1, maxy - miny + 1);
}
void AGS::draw_box(int index)
{
if(index == 0) {
// 全画面消去
box_fill(dest_screen, 0, 0, 639, 479, 0);
return;
}
int sx = box[index - 1].sx;
int sy = box[index - 1].sy;
int ex = box[index - 1].ex;
int ey = box[index - 1].ey;
uint8 color = box[index - 1].color;
if(1 <= index && index <= 10) {
box_fill(dest_screen, sx, sy, ex, ey, color);
} else if(11 <= index && index <= 20) {
box_line(dest_screen, sx, sy, ex, ey, color);
}
}
void AGS::draw_mesh(int sx, int sy, int width, int height)
{
// super d.p.s
for(int y = sy, h = 0; h < height && y < 480; y += 2, h += 2) {
for(int x = sx, w = 0; w < width && x < 640; x += 2, w += 2) {
vram[0][y][x] = 255;
}
for(int x = sx + 1, w = 1; w < width && x < 640; x += 2, w += 2) {
vram[0][y + 1][x] = 255;
}
}
draw_screen(sx, sy, width, height);
}
void AGS::box_fill(int dest, int sx, int sy, int ex, int ey, uint8 color)
{
for(int y = sy; y <= ey && y < 480; y++) {
for(int x = sx; x <= ex && x < 640; x++) {
vram[dest][y][x] = color;
}
}
if(dest == 0) {
draw_screen(sx, sy, ex - sx + 1, ey - sy + 1);
}
}
void AGS::box_line(int dest, int sx, int sy, int ex, int ey, uint8 color)
{
for(int x = sx; x <= ex && x < 640; x++) {
vram[dest][sy][x] = color;
vram[dest][ey][x] = color;
}
for(int y = sy; y <= ey && y < 480; y++) {
vram[dest][y][sx] = color;
vram[dest][y][ex] = color;
}
if(dest == 0) {
draw_screen(sx, sy, ex - sx + 1, ey - sy + 1);
}
}
/*
ALICE SOFT SYSTEM 3 for Win32
[ AGS - draw ]
*/
#include "ags.h"
#include <tuple>
#include <utility>
#include <vector>
#include <string.h>
#include "dri.h"
#include "crc32.h"
void AGS::load_cg(int page, int transparent)
{
if (nact->sys_ver == 3) {
// あゆみちゃん物語 フルカラー実写版
if(strncmp(acg, "CGA000.BMP", 10) == 0) {
char file_name[16];
sprintf(file_name, "CGA%03d.BMP", page);
load_bmp(file_name);
return;
} else if(strncmp(acg, "CGB000.BMP", 10) == 0) {
char file_name[16];
sprintf(file_name, "CGB%03d.BMP", page);
load_bmp(file_name);
return;
}
}
DRI* dri = new DRI();
int size;
uint8* data = dri->load(acg, page, &size);
if(data && size > 0) {
switch (nact->sys_ver) {
case 1:
switch (nact->crc32_a) {
case CRC32_BUNKASAI:
load_vsp(data, page, transparent);
break;
case CRC32_INTRUDER:
// load_gm3(data, page, transparent);
load_vsp(data, page, transparent); // 暫定
break;
case CRC32_VAMPIRE:
case CRC32_VAMPIRE_ENG:
load_vsp2l(data, page, transparent);
break;
default:
load_gl3(data, page, transparent);
break;
}
break;
case 2:
if(nact->crc32_a == CRC32_AYUMI_PROTO) {
// あゆみちゃん物語 PROTO
load_gl3(data, page, transparent);
} else if(nact->crc32_a == CRC32_AYUMI_FD || nact->crc32_a == CRC32_AYUMI_HINT) {
// あゆみちゃん物語
load_vsp(data, page, transparent);
} else if(nact->crc32_a == CRC32_SDPS) {
// Super D.P.S
load_pms(data, page, transparent);
} else {
if(data[0x8] == 0) {
load_vsp(data, page, transparent);
} else {
load_pms(data, page, transparent);
}
}
break;
case 3:
if(data[0x8] == 0) {
load_vsp(data, page, transparent);
} else {
load_pms(data, page, transparent);
}
break;
}
}
if (data)
free(data);
delete dri;
}
void AGS::copy(int sx, int sy, int ex, int ey, int dx, int dy)
{
#if 0
int width = ex - sx + 1;
int height = ey - sy + 1;
uint32 tmp[640 * 480];
memcpy(tmp, lpBmpScreen[src_screen], sizeof(tmp));
for(int y = 0; y < height && y + sy < 480 && y + dy < 480; y++) {
uint32* src = &tmp[640 * (479 - (y + sy))];
uint32* dest = vram[dest_screen][y + dy];
for(int x = 0; x < width && x + sx < 640 && x + dx < 640; x++) {
dest[x + dx] = src[x + sx];
}
}
if(dest_screen == 0) {
draw_screen(dx, dy, width, height);
}
#else
int width = ex - sx + 1;
int height = ey - sy + 1;
SDL_Rect srcrect = {sx, sy, width, height};
SDL_Rect destrect = {dx, dy, width, height};
SDL_UnlockSurface(hBmpScreen[src_screen]);
if (src_screen != dest_screen)
SDL_UnlockSurface(hBmpScreen[dest_screen]);
SDL_BlitSurface(hBmpScreen[src_screen], &srcrect, hBmpScreen[dest_screen], &destrect);
if (src_screen != dest_screen)
SDL_LockSurface(hBmpScreen[dest_screen]);
SDL_LockSurface(hBmpScreen[src_screen]);
if(dest_screen == 0) {
draw_screen(dx, dy, ex - sx + 1, ey - sy + 1);
}
#endif
}
void AGS::gcopy(int gsc, int gde, int glx, int gly, int gsw)
{
// N88-BASIC時代のコピーコマンド
int src = (gsw == 0 || gsw == 2) ? 0 : 1;
int dest = (gsw == 0 || gsw == 3) ? 0 : 1;
int sx = (gsc % 80) * 8;
int sy = gsc / 80;
int dx = (gde % 80) * 8;
int dy = gde / 80;
SDL_Rect srcrect = {sx, sy, glx * 8, gly};
SDL_Rect destrect = {dx, dy, glx * 8, gly};
SDL_UnlockSurface(hBmpScreen[src]);
if (src_screen != dest_screen)
SDL_UnlockSurface(hBmpScreen[dest]);
SDL_BlitSurface(hBmpScreen[src], &srcrect, hBmpScreen[dest], &destrect);
if (src_screen != dest_screen)
SDL_LockSurface(hBmpScreen[dest]);
SDL_LockSurface(hBmpScreen[src]);
if(dest == 0) {
draw_screen(dx, dy, glx * 8, gly);
}
}
void AGS::paint(int x, int y, uint8 color)
{
int old_color = vram[0][y][x];
if (old_color == color)
return;
int minx = x, maxx = x, miny = y, maxy = y;
std::vector<std::pair<int, int>> stack;
stack.push_back({x, y});
while (!stack.empty()) {
std::tie(x, y) = stack.back();
stack.pop_back();
while (x >= 0 && vram[0][y][x] == old_color) x--;
x++;
minx = std::min(x, minx);
bool span_above = false, span_below = false;
for (; x < 640 && vram[0][y][x] == old_color; x++) {
vram[0][y][x] = color;
if (y > 0) {
if (!span_above && vram[0][y - 1][x] == old_color) {
stack.push_back({x, y - 1});
span_above = true;
} else if (span_above && vram[0][y - 1][x] != old_color) {
span_above = false;
}
}
if (y < screen_height - 1) {
if (!span_below && vram[0][y + 1][x] == old_color) {
stack.push_back({x, y + 1});
span_below = true;
} else if (span_below && vram[0][y + 1][x] != old_color) {
span_below = false;
}
}
}
maxx = std::max(x - 1, maxx);
miny = std::min(y, miny);
maxy = std::max(y, maxy);
}
draw_screen(minx, miny, maxx - minx + 1, maxy - miny + 1);
}
void AGS::draw_box(int index)
{
if(index == 0) {
// 全画面消去
box_fill(dest_screen, 0, 0, 639, 479, 0);
return;
}
int sx = box[index - 1].sx;
int sy = box[index - 1].sy;
int ex = box[index - 1].ex;
int ey = box[index - 1].ey;
uint8 color = box[index - 1].color;
if(1 <= index && index <= 10) {
box_fill(dest_screen, sx, sy, ex, ey, color);
} else if(11 <= index && index <= 20) {
box_line(dest_screen, sx, sy, ex, ey, color);
}
}
void AGS::draw_mesh(int sx, int sy, int width, int height)
{
// super d.p.s
for(int y = sy, h = 0; h < height && y < 480; y += 2, h += 2) {
for(int x = sx, w = 0; w < width && x < 640; x += 2, w += 2) {
vram[0][y][x] = 255;
}
for(int x = sx + 1, w = 1; w < width && x < 640; x += 2, w += 2) {
vram[0][y + 1][x] = 255;
}
}
draw_screen(sx, sy, width, height);
}
void AGS::box_fill(int dest, int sx, int sy, int ex, int ey, uint8 color)
{
for(int y = sy; y <= ey && y < 480; y++) {
for(int x = sx; x <= ex && x < 640; x++) {
vram[dest][y][x] = color;
}
}
if(dest == 0) {
draw_screen(sx, sy, ex - sx + 1, ey - sy + 1);
}
}
void AGS::box_line(int dest, int sx, int sy, int ex, int ey, uint8 color)
{
for(int x = sx; x <= ex && x < 640; x++) {
vram[dest][sy][x] = color;
vram[dest][ey][x] = color;
}
for(int y = sy; y <= ey && y < 480; y++) {
vram[dest][y][sx] = color;
vram[dest][y][ex] = color;
}
if(dest == 0) {
draw_screen(sx, sy, ex - sx + 1, ey - sy + 1);
}
}
+151 -151
View File
@@ -1,151 +1,151 @@
/*
ALICE SOFT SYSTEM 1 for Win32
[ AGS - gl3 loader ]
*/
#include "ags.h"
#include <string.h>
void AGS::load_gl3(uint8* data, int page, int transparent)
{
// ヘッダ取得
uint16 tmp = (data[0x30] | (data[0x31] << 8)) - 0x8000;
int sx = tmp % 80;
int sy = tmp / 80;
int width = data[0x32] | (data[0x33] << 8);
int height = data[0x34] | (data[0x35] << 8);
uint8 base = 0;
// Jコマンドの処理
if(set_cg_dest) {
sx = cg_dest_x >> 3;
sy = cg_dest_y;
set_cg_dest = false;
}
// Zコマンドの処理
if(palette_bank != -1) {
base = (palette_bank & 0x0f) << 4;
}
// パレット取得
if(get_palette) {
for(int i = 0; i < 16; i++) {
uint32 b = data[i * 3 + 0];
uint32 r = data[i * 3 + 1];
uint32 g = data[i * 3 + 2];
program_palette[base + i] = SETPALETTE16(r, g, b);
}
}
// パレット展開
if(extract_palette && extract_palette_cg[page]) {
for(int i = 0; i < 16; i++) {
screen_palette[base + i] = program_palette[base + i];
}
}
// GL3展開
uint8 cgdata[4][80][3];
int p = 0x36;
memset(cgdata, 0, sizeof(cgdata));
for(int y = 0; y < height; y++) {
for(int pl = 0; pl < 4; pl++) {
int x = 0;
while(x < width) {
uint8 d1 = data[p++];
if(d1 == 0x0) {
uint8 d2 = data[p++];
if(d2 < 0x80) {
uint8 d3 = data[p++];
for(int i = 0; i < d2; i++) {
cgdata[pl][x++][0] = d3;
}
} else {
uint8 d3 = cgdata[pl][x + 1][2];
for(int i = 0; i < d2 - 0x80; i++) {
cgdata[pl][x++][0] = d3;
}
}
} else if(d1 == 0x1) {
cgdata[pl][x++][0] = data[p++];
} else if(0x2 <= d1 && d1 <= 0x7) {
uint8 d2 = data[p++];
for(int i = 0; i < d1; i++) {
cgdata[pl][x++][0] = d2;
}
} else if(0x8 <= d1 && d1 <= 0xd) {
uint8 d2 = cgdata[pl][x + 1][2];
for(int i = 0; i < d1 - 6; i++) {
cgdata[pl][x++][0] = d2;
}
} else if(d1 == 0xe) {
uint8 d2 = data[p++];
for(int i = 0; i < d2; i++) {
cgdata[pl][x][0] = cgdata[2][x][0];
x++;
}
} else if(d1 == 0xf) {
uint8 d2 = data[p++];
if(d2 < 0x80) {
for(int i = 0; i < d2; i++) {
cgdata[pl][x][0] = cgdata[0][x][0];
x++;
}
} else {
for(int i = 0; i < d2 - 0x80; i++) {
cgdata[pl][x][0] = cgdata[1][x][0];
x++;
}
}
} else {
cgdata[pl][x++][0] = d1;
}
}
}
// VRAMに転送
if(extract_cg) {
for(int x = 0; x < width; x++) {
for(int pl = 0; pl < 4; pl++) {
cgdata[pl][x][2] = cgdata[pl][x][1];
cgdata[pl][x][1] = cgdata[pl][x][0];
}
uint8 b0, b1, b2, b3, c[8];
b0 = cgdata[0][x][0];
b1 = cgdata[1][x][0];
b2 = cgdata[2][x][0];
b3 = cgdata[3][x][0];
c[0] = ((b0 >> 7) & 1) | ((b1 >> 6) & 2) | ((b2 >> 5) & 4) | ((b3 >> 4) & 8);
c[1] = ((b0 >> 6) & 1) | ((b1 >> 5) & 2) | ((b2 >> 4) & 4) | ((b3 >> 3) & 8);
c[2] = ((b0 >> 5) & 1) | ((b1 >> 4) & 2) | ((b2 >> 3) & 4) | ((b3 >> 2) & 8);
c[3] = ((b0 >> 4) & 1) | ((b1 >> 3) & 2) | ((b2 >> 2) & 4) | ((b3 >> 1) & 8);
c[4] = ((b0 >> 3) & 1) | ((b1 >> 2) & 2) | ((b2 >> 1) & 4) | ((b3 ) & 8);
c[5] = ((b0 >> 2) & 1) | ((b1 >> 1) & 2) | ((b2 ) & 4) | ((b3 << 1) & 8);
c[6] = ((b0 >> 1) & 1) | ((b1 ) & 2) | ((b2 << 1) & 4) | ((b3 << 2) & 8);
c[7] = ((b0 ) & 1) | ((b1 << 1) & 2) | ((b2 << 2) & 4) | ((b3 << 3) & 8);
uint32* dest = &vram[dest_screen][y + sy][(x + sx) * 8];
if(transparent == -1) {
for(int i = 0; i < 8; i++) {
dest[i] = c[i] | base;
}
} else {
for(int i = 0; i < 8; i++) {
if(c[i] != transparent) {
dest[i] = c[i] | base;
}
}
}
}
}
}
// 画面更新
if(dest_screen == 0 && extract_cg) {
draw_screen(sx * 8, sy, width * 8, height);
}
}
/*
ALICE SOFT SYSTEM 1 for Win32
[ AGS - gl3 loader ]
*/
#include "ags.h"
#include <string.h>
void AGS::load_gl3(uint8* data, int page, int transparent)
{
// ヘッダ取得
uint16 tmp = (data[0x30] | (data[0x31] << 8)) - 0x8000;
int sx = tmp % 80;
int sy = tmp / 80;
int width = data[0x32] | (data[0x33] << 8);
int height = data[0x34] | (data[0x35] << 8);
uint8 base = 0;
// Jコマンドの処理
if(set_cg_dest) {
sx = cg_dest_x >> 3;
sy = cg_dest_y;
set_cg_dest = false;
}
// Zコマンドの処理
if(palette_bank != -1) {
base = (palette_bank & 0x0f) << 4;
}
// パレット取得
if(get_palette) {
for(int i = 0; i < 16; i++) {
uint32 b = data[i * 3 + 0];
uint32 r = data[i * 3 + 1];
uint32 g = data[i * 3 + 2];
program_palette[base + i] = SETPALETTE16(r, g, b);
}
}
// パレット展開
if(extract_palette && extract_palette_cg[page]) {
for(int i = 0; i < 16; i++) {
screen_palette[base + i] = program_palette[base + i];
}
}
// GL3展開
uint8 cgdata[4][80][3];
int p = 0x36;
memset(cgdata, 0, sizeof(cgdata));
for(int y = 0; y < height; y++) {
for(int pl = 0; pl < 4; pl++) {
int x = 0;
while(x < width) {
uint8 d1 = data[p++];
if(d1 == 0x0) {
uint8 d2 = data[p++];
if(d2 < 0x80) {
uint8 d3 = data[p++];
for(int i = 0; i < d2; i++) {
cgdata[pl][x++][0] = d3;
}
} else {
uint8 d3 = cgdata[pl][x + 1][2];
for(int i = 0; i < d2 - 0x80; i++) {
cgdata[pl][x++][0] = d3;
}
}
} else if(d1 == 0x1) {
cgdata[pl][x++][0] = data[p++];
} else if(0x2 <= d1 && d1 <= 0x7) {
uint8 d2 = data[p++];
for(int i = 0; i < d1; i++) {
cgdata[pl][x++][0] = d2;
}
} else if(0x8 <= d1 && d1 <= 0xd) {
uint8 d2 = cgdata[pl][x + 1][2];
for(int i = 0; i < d1 - 6; i++) {
cgdata[pl][x++][0] = d2;
}
} else if(d1 == 0xe) {
uint8 d2 = data[p++];
for(int i = 0; i < d2; i++) {
cgdata[pl][x][0] = cgdata[2][x][0];
x++;
}
} else if(d1 == 0xf) {
uint8 d2 = data[p++];
if(d2 < 0x80) {
for(int i = 0; i < d2; i++) {
cgdata[pl][x][0] = cgdata[0][x][0];
x++;
}
} else {
for(int i = 0; i < d2 - 0x80; i++) {
cgdata[pl][x][0] = cgdata[1][x][0];
x++;
}
}
} else {
cgdata[pl][x++][0] = d1;
}
}
}
// VRAMに転送
if(extract_cg) {
for(int x = 0; x < width; x++) {
for(int pl = 0; pl < 4; pl++) {
cgdata[pl][x][2] = cgdata[pl][x][1];
cgdata[pl][x][1] = cgdata[pl][x][0];
}
uint8 b0, b1, b2, b3, c[8];
b0 = cgdata[0][x][0];
b1 = cgdata[1][x][0];
b2 = cgdata[2][x][0];
b3 = cgdata[3][x][0];
c[0] = ((b0 >> 7) & 1) | ((b1 >> 6) & 2) | ((b2 >> 5) & 4) | ((b3 >> 4) & 8);
c[1] = ((b0 >> 6) & 1) | ((b1 >> 5) & 2) | ((b2 >> 4) & 4) | ((b3 >> 3) & 8);
c[2] = ((b0 >> 5) & 1) | ((b1 >> 4) & 2) | ((b2 >> 3) & 4) | ((b3 >> 2) & 8);
c[3] = ((b0 >> 4) & 1) | ((b1 >> 3) & 2) | ((b2 >> 2) & 4) | ((b3 >> 1) & 8);
c[4] = ((b0 >> 3) & 1) | ((b1 >> 2) & 2) | ((b2 >> 1) & 4) | ((b3 ) & 8);
c[5] = ((b0 >> 2) & 1) | ((b1 >> 1) & 2) | ((b2 ) & 4) | ((b3 << 1) & 8);
c[6] = ((b0 >> 1) & 1) | ((b1 ) & 2) | ((b2 << 1) & 4) | ((b3 << 2) & 8);
c[7] = ((b0 ) & 1) | ((b1 << 1) & 2) | ((b2 << 2) & 4) | ((b3 << 3) & 8);
uint32* dest = &vram[dest_screen][y + sy][(x + sx) * 8];
if(transparent == -1) {
for(int i = 0; i < 8; i++) {
dest[i] = c[i] | base;
}
} else {
for(int i = 0; i < 8; i++) {
if(c[i] != transparent) {
dest[i] = c[i] | base;
}
}
}
}
}
}
// 画面更新
if(dest_screen == 0 && extract_cg) {
draw_screen(sx * 8, sy, width * 8, height);
}
}
+153 -153
View File
@@ -1,153 +1,153 @@
/*
ALICE SOFT SYSTEM 1 for Win32
[ AGS - gm3 loader ]
*/
#include "ags.h"
#include <string.h>
void AGS::load_gm3(uint8* data, int page, int transparent)
{
// ヘッダ取得
uint16 tmp = (data[0x30] | (data[0x31] << 8)) - 0x8000;
int sx = tmp % 80;
int sy = tmp / 80;
int width = data[0x32] | (data[0x33] << 8);
int height = data[0x34] | (data[0x35] << 8);
uint8 base = 0;
// Jコマンドの処理
if(set_cg_dest) {
sx = cg_dest_x >> 3;
sy = cg_dest_y;
set_cg_dest = false;
}
// Zコマンドの処理
if(palette_bank != -1) {
base = (palette_bank & 0x0f) << 4;
}
/*
// パレット取得
if(get_palette) {
for(int i = 0; i < 16; i++) {
uint32 b = data[i * 3 + 0] & 0xf;
uint32 r = data[i * 3 + 1] & 0xf;
uint32 g = data[i * 3 + 2] & 0xf;
program_palette[base + i] = SETPALETTE16(r, g, b);
}
}
// パレット展開
if(extract_palette && extract_palette_cg[page]) {
for(int i = 0; i < 16; i++) {
screen_palette[base + i] = program_palette[base + i];
}
}
*/
// GM3展開
uint8 cgdata[3][80][3];
int p = 0x36;
memset(cgdata, 0, sizeof(cgdata));
for(int y = 0; y < height; y++) {
for(int pl = 0; pl < 3; pl++) {
int x = 0;
while(x < width) {
uint8 d1 = data[p++];
if(d1 == 0x0) {
uint8 d2 = data[p++];
if(d2 < 0x80) {
uint8 d3 = data[p++];
for(int i = 0; i < d2; i++) {
cgdata[pl][x++][0] = d3;
}
} else {
uint8 d3 = cgdata[pl][x + 1][2];
for(int i = 0; i < d2 - 0x80; i++) {
cgdata[pl][x++][0] = d3;
}
}
} else if(d1 == 0x1) {
cgdata[pl][x++][0] = data[p++];
} else if(0x2 <= d1 && d1 <= 0x7) {
uint8 d2 = data[p++];
for(int i = 0; i < d1; i++) {
cgdata[pl][x++][0] = d2;
}
} else if(0x8 <= d1 && d1 <= 0xd) {
uint8 d2 = cgdata[pl][x + 1][2];
for(int i = 0; i < d1 - 6; i++) {
cgdata[pl][x++][0] = d2;
}
} else if(d1 == 0xe) {
uint8 d2 = data[p++];
for(int i = 0; i < d2; i++) {
cgdata[pl][x][0] = cgdata[2][x][0];
x++;
}
} else if(d1 == 0xf) {
uint8 d2 = data[p++];
if(d2 < 0x80) {
for(int i = 0; i < d2; i++) {
cgdata[pl][x][0] = cgdata[0][x][0];
x++;
}
} else {
for(int i = 0; i < d2 - 0x80; i++) {
cgdata[pl][x][0] = cgdata[1][x][0];
x++;
}
}
} else {
cgdata[pl][x++][0] = d1;
}
}
}
// VRAMに転送
if(extract_cg) {
for(int x = 0; x < width; x++) {
for(int pl = 0; pl < 3; pl++) {
cgdata[pl][x][2] = cgdata[pl][x][1];
cgdata[pl][x][1] = cgdata[pl][x][0];
}
uint8 b0, b1, b2, c[8];
b0 = cgdata[0][x][0];
b1 = cgdata[1][x][0];
b2 = cgdata[2][x][0];
c[0] = ((b0 >> 7) & 1) | ((b1 >> 6) & 2) | ((b2 >> 5) & 4);
c[1] = ((b0 >> 6) & 1) | ((b1 >> 5) & 2) | ((b2 >> 4) & 4);
c[2] = ((b0 >> 5) & 1) | ((b1 >> 4) & 2) | ((b2 >> 3) & 4);
c[3] = ((b0 >> 4) & 1) | ((b1 >> 3) & 2) | ((b2 >> 2) & 4);
c[4] = ((b0 >> 3) & 1) | ((b1 >> 2) & 2) | ((b2 >> 1) & 4);
c[5] = ((b0 >> 2) & 1) | ((b1 >> 1) & 2) | ((b2 ) & 4);
c[6] = ((b0 >> 1) & 1) | ((b1 ) & 2) | ((b2 << 1) & 4);
c[7] = ((b0 ) & 1) | ((b1 << 1) & 2) | ((b2 << 2) & 4);
uint32* dest0 = &vram[dest_screen][(y + sy) * 2 + 0][(x + sx) * 8];
uint32* dest1 = &vram[dest_screen][(y + sy) * 2 + 1][(x + sx) * 8];
if(transparent == -1) {
for(int i = 0; i < 8; i++) {
dest0[i] = dest1[i] = c[i] | base;
}
} else {
for(int i = 0; i < 8; i++) {
if(c[i] != transparent) {
dest0[i] = dest1[i] = c[i] | base;
}
}
}
}
}
}
// 画面更新
if(dest_screen == 0 && extract_cg) {
draw_screen(sx * 8, sy * 2, width * 8, height * 2);
}
}
/*
ALICE SOFT SYSTEM 1 for Win32
[ AGS - gm3 loader ]
*/
#include "ags.h"
#include <string.h>
void AGS::load_gm3(uint8* data, int page, int transparent)
{
// ヘッダ取得
uint16 tmp = (data[0x30] | (data[0x31] << 8)) - 0x8000;
int sx = tmp % 80;
int sy = tmp / 80;
int width = data[0x32] | (data[0x33] << 8);
int height = data[0x34] | (data[0x35] << 8);
uint8 base = 0;
// Jコマンドの処理
if(set_cg_dest) {
sx = cg_dest_x >> 3;
sy = cg_dest_y;
set_cg_dest = false;
}
// Zコマンドの処理
if(palette_bank != -1) {
base = (palette_bank & 0x0f) << 4;
}
/*
// パレット取得
if(get_palette) {
for(int i = 0; i < 16; i++) {
uint32 b = data[i * 3 + 0] & 0xf;
uint32 r = data[i * 3 + 1] & 0xf;
uint32 g = data[i * 3 + 2] & 0xf;
program_palette[base + i] = SETPALETTE16(r, g, b);
}
}
// パレット展開
if(extract_palette && extract_palette_cg[page]) {
for(int i = 0; i < 16; i++) {
screen_palette[base + i] = program_palette[base + i];
}
}
*/
// GM3展開
uint8 cgdata[3][80][3];
int p = 0x36;
memset(cgdata, 0, sizeof(cgdata));
for(int y = 0; y < height; y++) {
for(int pl = 0; pl < 3; pl++) {
int x = 0;
while(x < width) {
uint8 d1 = data[p++];
if(d1 == 0x0) {
uint8 d2 = data[p++];
if(d2 < 0x80) {
uint8 d3 = data[p++];
for(int i = 0; i < d2; i++) {
cgdata[pl][x++][0] = d3;
}
} else {
uint8 d3 = cgdata[pl][x + 1][2];
for(int i = 0; i < d2 - 0x80; i++) {
cgdata[pl][x++][0] = d3;
}
}
} else if(d1 == 0x1) {
cgdata[pl][x++][0] = data[p++];
} else if(0x2 <= d1 && d1 <= 0x7) {
uint8 d2 = data[p++];
for(int i = 0; i < d1; i++) {
cgdata[pl][x++][0] = d2;
}
} else if(0x8 <= d1 && d1 <= 0xd) {
uint8 d2 = cgdata[pl][x + 1][2];
for(int i = 0; i < d1 - 6; i++) {
cgdata[pl][x++][0] = d2;
}
} else if(d1 == 0xe) {
uint8 d2 = data[p++];
for(int i = 0; i < d2; i++) {
cgdata[pl][x][0] = cgdata[2][x][0];
x++;
}
} else if(d1 == 0xf) {
uint8 d2 = data[p++];
if(d2 < 0x80) {
for(int i = 0; i < d2; i++) {
cgdata[pl][x][0] = cgdata[0][x][0];
x++;
}
} else {
for(int i = 0; i < d2 - 0x80; i++) {
cgdata[pl][x][0] = cgdata[1][x][0];
x++;
}
}
} else {
cgdata[pl][x++][0] = d1;
}
}
}
// VRAMに転送
if(extract_cg) {
for(int x = 0; x < width; x++) {
for(int pl = 0; pl < 3; pl++) {
cgdata[pl][x][2] = cgdata[pl][x][1];
cgdata[pl][x][1] = cgdata[pl][x][0];
}
uint8 b0, b1, b2, c[8];
b0 = cgdata[0][x][0];
b1 = cgdata[1][x][0];
b2 = cgdata[2][x][0];
c[0] = ((b0 >> 7) & 1) | ((b1 >> 6) & 2) | ((b2 >> 5) & 4);
c[1] = ((b0 >> 6) & 1) | ((b1 >> 5) & 2) | ((b2 >> 4) & 4);
c[2] = ((b0 >> 5) & 1) | ((b1 >> 4) & 2) | ((b2 >> 3) & 4);
c[3] = ((b0 >> 4) & 1) | ((b1 >> 3) & 2) | ((b2 >> 2) & 4);
c[4] = ((b0 >> 3) & 1) | ((b1 >> 2) & 2) | ((b2 >> 1) & 4);
c[5] = ((b0 >> 2) & 1) | ((b1 >> 1) & 2) | ((b2 ) & 4);
c[6] = ((b0 >> 1) & 1) | ((b1 ) & 2) | ((b2 << 1) & 4);
c[7] = ((b0 ) & 1) | ((b1 << 1) & 2) | ((b2 << 2) & 4);
uint32* dest0 = &vram[dest_screen][(y + sy) * 2 + 0][(x + sx) * 8];
uint32* dest1 = &vram[dest_screen][(y + sy) * 2 + 1][(x + sx) * 8];
if(transparent == -1) {
for(int i = 0; i < 8; i++) {
dest0[i] = dest1[i] = c[i] | base;
}
} else {
for(int i = 0; i < 8; i++) {
if(c[i] != transparent) {
dest0[i] = dest1[i] = c[i] | base;
}
}
}
}
}
}
// 画面更新
if(dest_screen == 0 && extract_cg) {
draw_screen(sx * 8, sy * 2, width * 8, height * 2);
}
}
+184 -184
View File
@@ -1,184 +1,184 @@
/*
ALICE SOFT SYSTEM 3 for Win32
[ AGS - pms loader ]
*/
#include "ags.h"
#include "crc32.h"
#include <string.h>
void AGS::load_pms(uint8* data, int page, int transparent)
{
// ヘッダ取得
int sx = data[0x0] | (data[0x1] << 8);
int sy = data[0x2] | (data[0x3] << 8);
int ex = data[0x4] | (data[0x5] << 8);
int ey = data[0x6] | (data[0x7] << 8);
int width = ex - sx + 1;
int height = ey - sy + 1;
uint8 mask = data[0xa];
// Jコマンドの処理
if(set_cg_dest) {
sx = cg_dest_x;
sy = cg_dest_y;
ex = sx + width - 1;
ey = sy + height - 1;
set_cg_dest = false;
}
// パレット取得
uint32 tmp_palette[256];
if(get_palette) {
int p = 0x20;
for(int i = 0; i < 16; i++) {
for(int j = 0; j < 16; j++) {
uint32 r = data[p++];
uint32 g = data[p++];
uint32 b = data[p++];
tmp_palette[i * 16 + j] = SETPALETTE256(r, g, b);
}
}
if(nact->crc32_a == CRC32_RANCE41 ||
nact->crc32_a == CRC32_RANCE41_ENG ||
nact->crc32_a == CRC32_RANCE42 ||
nact->crc32_a == CRC32_RANCE42_ENG ||
nact->crc32_a == CRC32_HASHIRIONNA2) {
// 上下16色は取得しない
for(int i = 1; i < 15; i++) {
for(int j = 0; j < 16; j++) {
if(!(mask & (0x01 << i))) {
program_palette[i * 16 + j] = tmp_palette[i * 16 + j];
}
}
}
} else if(nact->crc32_a == CRC32_MUGENHOUYOU && transparent != -1) {
// Uコマンドでは上下32色は取得しない
for(int i = 2; i < 14; i++) {
for(int j = 0; j < 16; j++) {
if(!(mask & (0x01 << i))) {
program_palette[i * 16 + j] = tmp_palette[i * 16 + j];
}
}
}
} else {
for(int i = 0; i < 16; i++) {
for(int j = 0; j < 16; j++) {
if(!(mask & (0x01 << i))) {
program_palette[i * 16 + j] = tmp_palette[i * 16 + j];
}
}
}
}
}
// パレット展開
if (nact->sys_ver == 3) {
if((extract_palette && extract_palette_cg[page]) || nact->crc32_a == CRC32_FUNNYBEE_CD) {
if(nact->crc32_a == CRC32_RANCE41 ||
nact->crc32_a == CRC32_RANCE41_ENG ||
nact->crc32_a == CRC32_RANCE42 ||
nact->crc32_a == CRC32_RANCE42_ENG ||
nact->crc32_a == CRC32_HASHIRIONNA2) {
// 上下16色は展開しない
for(int i = 1; i < 15; i++) {
for(int j = 0; j < 16; j++) {
if(!(mask & (0x01 << i))) {
screen_palette[i * 16 + j] = program_palette[i * 16 + j];
}
}
}
} else if(nact->crc32_a == CRC32_MUGENHOUYOU && transparent != -1) {
// Uコマンドでは上下32色は展開しない
for(int i = 2; i < 14; i++) {
for(int j = 0; j < 16; j++) {
if(!(mask & (0x01 << i))) {
screen_palette[i * 16 + j] = program_palette[i * 16 + j];
}
}
}
} else {
for(int i = 0; i < 16; i++) {
for(int j = 0; j < 16; j++) {
if(!(mask & (0x01 << i))) {
screen_palette[i * 16 + j] = program_palette[i * 16 + j];
}
}
}
}
}
} else if(extract_palette && extract_palette_cg[page]) {
for(int i = 0; i < 16; i++) {
for(int j = 0; j < 16; j++) {
if(!(mask & (0x01 << i))) {
screen_palette[i * 16 + j] = program_palette[i * 16 + j];
}
}
}
}
// PMS展開
uint8 cgdata[3][640];
int p = 0x320;
memset(cgdata, 0, sizeof(cgdata));
for(int y = 0; y < height; y++) {
int x = 0;
while(x < width) {
uint8 d1 = data[p++];
if(d1 == 0xff) {
int length = data[p++] + 3;
memcpy(cgdata[0] + x, cgdata[1] + x, length);
x += length;
} else if(d1 == 0xfe) {
int length = data[p++] + 3;
memcpy(cgdata[0] + x, cgdata[2] + x, length);
x += length;
} else if(d1 == 0xfd) {
int length = data[p++] + 4;
uint8 d2 = data[p++];
memset(cgdata[0] + x, d2, length);
x += length;
} else if(d1 == 0xfc) {
int length = data[p++] + 3;
uint8 d2 = data[p++];
uint8 d3 = data[p++];
for(int i = 0; i < length; i++) {
cgdata[0][x++] = d2;
cgdata[0][x++] = d3;
}
} else if(d1 == 0xfb || d1 == 0xfa || d1 == 0xf9 || d1 == 0xf8) {
cgdata[0][x++] = data[p++];
} else {
cgdata[0][x++] = d1;
}
}
// VRAMに転送
if(extract_cg) {
uint32* dest = &vram[dest_screen][y + sy][sx];
if(transparent == -1) {
for(int x = 0; x < width; x++) {
cgdata[2][x] = cgdata[1][x];
cgdata[1][x] = cgdata[0][x];
dest[x] = cgdata[0][x];
}
} else {
for(int x = 0; x < width; x++) {
cgdata[2][x] = cgdata[1][x];
cgdata[1][x] = cgdata[0][x];
if(cgdata[0][x] != transparent) {
dest[x] = cgdata[0][x];
}
}
}
}
}
// 画面更新
if(dest_screen == 0 && extract_cg) {
draw_screen(sx, sy, width, height);
}
}
/*
ALICE SOFT SYSTEM 3 for Win32
[ AGS - pms loader ]
*/
#include "ags.h"
#include "crc32.h"
#include <string.h>
void AGS::load_pms(uint8* data, int page, int transparent)
{
// ヘッダ取得
int sx = data[0x0] | (data[0x1] << 8);
int sy = data[0x2] | (data[0x3] << 8);
int ex = data[0x4] | (data[0x5] << 8);
int ey = data[0x6] | (data[0x7] << 8);
int width = ex - sx + 1;
int height = ey - sy + 1;
uint8 mask = data[0xa];
// Jコマンドの処理
if(set_cg_dest) {
sx = cg_dest_x;
sy = cg_dest_y;
ex = sx + width - 1;
ey = sy + height - 1;
set_cg_dest = false;
}
// パレット取得
uint32 tmp_palette[256];
if(get_palette) {
int p = 0x20;
for(int i = 0; i < 16; i++) {
for(int j = 0; j < 16; j++) {
uint32 r = data[p++];
uint32 g = data[p++];
uint32 b = data[p++];
tmp_palette[i * 16 + j] = SETPALETTE256(r, g, b);
}
}
if(nact->crc32_a == CRC32_RANCE41 ||
nact->crc32_a == CRC32_RANCE41_ENG ||
nact->crc32_a == CRC32_RANCE42 ||
nact->crc32_a == CRC32_RANCE42_ENG ||
nact->crc32_a == CRC32_HASHIRIONNA2) {
// 上下16色は取得しない
for(int i = 1; i < 15; i++) {
for(int j = 0; j < 16; j++) {
if(!(mask & (0x01 << i))) {
program_palette[i * 16 + j] = tmp_palette[i * 16 + j];
}
}
}
} else if(nact->crc32_a == CRC32_MUGENHOUYOU && transparent != -1) {
// Uコマンドでは上下32色は取得しない
for(int i = 2; i < 14; i++) {
for(int j = 0; j < 16; j++) {
if(!(mask & (0x01 << i))) {
program_palette[i * 16 + j] = tmp_palette[i * 16 + j];
}
}
}
} else {
for(int i = 0; i < 16; i++) {
for(int j = 0; j < 16; j++) {
if(!(mask & (0x01 << i))) {
program_palette[i * 16 + j] = tmp_palette[i * 16 + j];
}
}
}
}
}
// パレット展開
if (nact->sys_ver == 3) {
if((extract_palette && extract_palette_cg[page]) || nact->crc32_a == CRC32_FUNNYBEE_CD) {
if(nact->crc32_a == CRC32_RANCE41 ||
nact->crc32_a == CRC32_RANCE41_ENG ||
nact->crc32_a == CRC32_RANCE42 ||
nact->crc32_a == CRC32_RANCE42_ENG ||
nact->crc32_a == CRC32_HASHIRIONNA2) {
// 上下16色は展開しない
for(int i = 1; i < 15; i++) {
for(int j = 0; j < 16; j++) {
if(!(mask & (0x01 << i))) {
screen_palette[i * 16 + j] = program_palette[i * 16 + j];
}
}
}
} else if(nact->crc32_a == CRC32_MUGENHOUYOU && transparent != -1) {
// Uコマンドでは上下32色は展開しない
for(int i = 2; i < 14; i++) {
for(int j = 0; j < 16; j++) {
if(!(mask & (0x01 << i))) {
screen_palette[i * 16 + j] = program_palette[i * 16 + j];
}
}
}
} else {
for(int i = 0; i < 16; i++) {
for(int j = 0; j < 16; j++) {
if(!(mask & (0x01 << i))) {
screen_palette[i * 16 + j] = program_palette[i * 16 + j];
}
}
}
}
}
} else if(extract_palette && extract_palette_cg[page]) {
for(int i = 0; i < 16; i++) {
for(int j = 0; j < 16; j++) {
if(!(mask & (0x01 << i))) {
screen_palette[i * 16 + j] = program_palette[i * 16 + j];
}
}
}
}
// PMS展開
uint8 cgdata[3][640];
int p = 0x320;
memset(cgdata, 0, sizeof(cgdata));
for(int y = 0; y < height; y++) {
int x = 0;
while(x < width) {
uint8 d1 = data[p++];
if(d1 == 0xff) {
int length = data[p++] + 3;
memcpy(cgdata[0] + x, cgdata[1] + x, length);
x += length;
} else if(d1 == 0xfe) {
int length = data[p++] + 3;
memcpy(cgdata[0] + x, cgdata[2] + x, length);
x += length;
} else if(d1 == 0xfd) {
int length = data[p++] + 4;
uint8 d2 = data[p++];
memset(cgdata[0] + x, d2, length);
x += length;
} else if(d1 == 0xfc) {
int length = data[p++] + 3;
uint8 d2 = data[p++];
uint8 d3 = data[p++];
for(int i = 0; i < length; i++) {
cgdata[0][x++] = d2;
cgdata[0][x++] = d3;
}
} else if(d1 == 0xfb || d1 == 0xfa || d1 == 0xf9 || d1 == 0xf8) {
cgdata[0][x++] = data[p++];
} else {
cgdata[0][x++] = d1;
}
}
// VRAMに転送
if(extract_cg) {
uint32* dest = &vram[dest_screen][y + sy][sx];
if(transparent == -1) {
for(int x = 0; x < width; x++) {
cgdata[2][x] = cgdata[1][x];
cgdata[1][x] = cgdata[0][x];
dest[x] = cgdata[0][x];
}
} else {
for(int x = 0; x < width; x++) {
cgdata[2][x] = cgdata[1][x];
cgdata[1][x] = cgdata[0][x];
if(cgdata[0][x] != transparent) {
dest[x] = cgdata[0][x];
}
}
}
}
}
// 画面更新
if(dest_screen == 0 && extract_cg) {
draw_screen(sx, sy, width, height);
}
}
+547 -547
View File
File diff suppressed because it is too large Load Diff
+165 -165
View File
@@ -1,165 +1,165 @@
/*
ALICE SOFT SYSTEM 3 for Win32
[ AGS - vsp loader ]
*/
#include "ags.h"
#include "crc32.h"
#include <string.h>
void AGS::load_vsp(uint8* data, int page, int transparent)
{
// ヘッダ取得
int sx = data[0] | (data[1] << 8);
int sy = data[2] | (data[3] << 8);
int ex = data[4] | (data[5] << 8);
int ey = data[6] | (data[7] << 8);
int width = ex - sx;
int height = ey - sy;
uint8 base = (data[9] & 0x0f) << 4;
// Jコマンドの処理
if(set_cg_dest) {
sx = cg_dest_x >> 3;
sy = cg_dest_y;
ex = sx + width;
ey = sy + height;
set_cg_dest = false;
}
// Zコマンドの処理
if(nact->crc32_a == CRC32_AMBIVALENZ_FD || nact->crc32_a == CRC32_AMBIVALENZ_CD) {
// Z 0,numを無視する
} else {
if(palette_bank != -1) {
base = (palette_bank & 0x0f) << 4;
}
}
// パレット取得
if(get_palette && transparent != 101) {
int p = 0x0a;
for(int i = 0; i < 16; i++) {
uint32 b = data[p++] & 0xf;
uint32 r = data[p++] & 0xf;
uint32 g = data[p++] & 0xf;
program_palette[base + i] = SETPALETTE16(r, g, b);
}
}
// パレット展開
if(nact->crc32_a == CRC32_FUNNYBEE_FD || nact->crc32_a == CRC32_FUNNYBEE_CD || nact->crc32_a == CRC32_FUNNYBEE_PATCH) {
if(extract_palette_cg[page]) {
for(int i = 0; i < 16; i++) {
screen_palette[base + i] = program_palette[base + i];
}
}
} else {
if(extract_palette && extract_palette_cg[page]) {
for(int i = 0; i < 16; i++) {
screen_palette[base + i] = program_palette[base + i];
}
}
}
// VSP展開
uint8 cgdata[4][2][480], mask = 0;
int p = 0x3a;
memset(cgdata, 0, sizeof(cgdata));
for(int x = 0; x < width; x++) {
for(int pl = 0; pl < 4; pl++) {
int y = 0;
while(y < height) {
uint8 d1 = data[p++];
if(d1 == 0) {
int length = data[p++] + 1;
for(int i = 0; i < length; i++) {
cgdata[pl][0][y] = cgdata[pl][1][y];
y++;
}
} else if(d1 == 1) {
int length = data[p++] + 1;
uint8 d2 = data[p++];
for(int i = 0; i < length; i++) {
cgdata[pl][0][y++] = d2;
}
} else if(d1 == 2) {
int length = data[p++] + 1;
uint8 d2 = data[p++];
uint8 d3 = data[p++];
for(int i = 0; i < length; i++) {
cgdata[pl][0][y++] = d2;
cgdata[pl][0][y++] = d3;
}
} else if(d1 == 3) {
int length = data[p++] + 1;
for(int i = 0; i < length; i++) {
cgdata[pl][0][y] = cgdata[0][0][y] ^ mask;
y++;
}
mask = 0;
} else if(d1 == 4) {
int length = data[p++] + 1;
for(int i = 0; i < length; i++) {
cgdata[pl][0][y] = cgdata[1][0][y] ^ mask;
y++;
}
mask = 0;
} else if(d1 == 5) {
int length = data[p++] + 1;
for(int i = 0; i < length; i++) {
cgdata[pl][0][y] = cgdata[2][0][y] ^ mask;
y++;
}
mask = 0;
} else if(d1 == 6) {
mask = 0xff;
} else if(d1 == 7) {
cgdata[pl][0][y++] = data[p++];
} else {
cgdata[pl][0][y++] = d1;
}
}
}
// VRAMに転送
if(extract_cg) {
for(int y = 0; y < height; y++) {
uint8 b0, b1, b2, b3, c[8];
b0 = cgdata[0][1][y] = cgdata[0][0][y];
b1 = cgdata[1][1][y] = cgdata[1][0][y];
b2 = cgdata[2][1][y] = cgdata[2][0][y];
b3 = cgdata[3][1][y] = cgdata[3][0][y];
c[0] = ((b0 >> 7) & 1) | ((b1 >> 6) & 2) | ((b2 >> 5) & 4) | ((b3 >> 4) & 8);
c[1] = ((b0 >> 6) & 1) | ((b1 >> 5) & 2) | ((b2 >> 4) & 4) | ((b3 >> 3) & 8);
c[2] = ((b0 >> 5) & 1) | ((b1 >> 4) & 2) | ((b2 >> 3) & 4) | ((b3 >> 2) & 8);
c[3] = ((b0 >> 4) & 1) | ((b1 >> 3) & 2) | ((b2 >> 2) & 4) | ((b3 >> 1) & 8);
c[4] = ((b0 >> 3) & 1) | ((b1 >> 2) & 2) | ((b2 >> 1) & 4) | ((b3 ) & 8);
c[5] = ((b0 >> 2) & 1) | ((b1 >> 1) & 2) | ((b2 ) & 4) | ((b3 << 1) & 8);
c[6] = ((b0 >> 1) & 1) | ((b1 ) & 2) | ((b2 << 1) & 4) | ((b3 << 2) & 8);
c[7] = ((b0 ) & 1) | ((b1 << 1) & 2) | ((b2 << 2) & 4) | ((b3 << 3) & 8);
uint32* dest = &vram[dest_screen][y + sy][(x + sx) * 8];
if(transparent == -1) {
for(int i = 0; i < 8; i++) {
dest[i] = c[i] | base;
}
} else {
for(int i = 0; i < 8; i++) {
if(c[i] != transparent) {
dest[i] = c[i] | base;
}
}
}
}
}
}
// 画面更新
if(dest_screen == 0 && extract_cg) {
draw_screen(sx * 8, sy, width * 8, height);
}
}
/*
ALICE SOFT SYSTEM 3 for Win32
[ AGS - vsp loader ]
*/
#include "ags.h"
#include "crc32.h"
#include <string.h>
void AGS::load_vsp(uint8* data, int page, int transparent)
{
// ヘッダ取得
int sx = data[0] | (data[1] << 8);
int sy = data[2] | (data[3] << 8);
int ex = data[4] | (data[5] << 8);
int ey = data[6] | (data[7] << 8);
int width = ex - sx;
int height = ey - sy;
uint8 base = (data[9] & 0x0f) << 4;
// Jコマンドの処理
if(set_cg_dest) {
sx = cg_dest_x >> 3;
sy = cg_dest_y;
ex = sx + width;
ey = sy + height;
set_cg_dest = false;
}
// Zコマンドの処理
if(nact->crc32_a == CRC32_AMBIVALENZ_FD || nact->crc32_a == CRC32_AMBIVALENZ_CD) {
// Z 0,numを無視する
} else {
if(palette_bank != -1) {
base = (palette_bank & 0x0f) << 4;
}
}
// パレット取得
if(get_palette && transparent != 101) {
int p = 0x0a;
for(int i = 0; i < 16; i++) {
uint32 b = data[p++] & 0xf;
uint32 r = data[p++] & 0xf;
uint32 g = data[p++] & 0xf;
program_palette[base + i] = SETPALETTE16(r, g, b);
}
}
// パレット展開
if(nact->crc32_a == CRC32_FUNNYBEE_FD || nact->crc32_a == CRC32_FUNNYBEE_CD || nact->crc32_a == CRC32_FUNNYBEE_PATCH) {
if(extract_palette_cg[page]) {
for(int i = 0; i < 16; i++) {
screen_palette[base + i] = program_palette[base + i];
}
}
} else {
if(extract_palette && extract_palette_cg[page]) {
for(int i = 0; i < 16; i++) {
screen_palette[base + i] = program_palette[base + i];
}
}
}
// VSP展開
uint8 cgdata[4][2][480], mask = 0;
int p = 0x3a;
memset(cgdata, 0, sizeof(cgdata));
for(int x = 0; x < width; x++) {
for(int pl = 0; pl < 4; pl++) {
int y = 0;
while(y < height) {
uint8 d1 = data[p++];
if(d1 == 0) {
int length = data[p++] + 1;
for(int i = 0; i < length; i++) {
cgdata[pl][0][y] = cgdata[pl][1][y];
y++;
}
} else if(d1 == 1) {
int length = data[p++] + 1;
uint8 d2 = data[p++];
for(int i = 0; i < length; i++) {
cgdata[pl][0][y++] = d2;
}
} else if(d1 == 2) {
int length = data[p++] + 1;
uint8 d2 = data[p++];
uint8 d3 = data[p++];
for(int i = 0; i < length; i++) {
cgdata[pl][0][y++] = d2;
cgdata[pl][0][y++] = d3;
}
} else if(d1 == 3) {
int length = data[p++] + 1;
for(int i = 0; i < length; i++) {
cgdata[pl][0][y] = cgdata[0][0][y] ^ mask;
y++;
}
mask = 0;
} else if(d1 == 4) {
int length = data[p++] + 1;
for(int i = 0; i < length; i++) {
cgdata[pl][0][y] = cgdata[1][0][y] ^ mask;
y++;
}
mask = 0;
} else if(d1 == 5) {
int length = data[p++] + 1;
for(int i = 0; i < length; i++) {
cgdata[pl][0][y] = cgdata[2][0][y] ^ mask;
y++;
}
mask = 0;
} else if(d1 == 6) {
mask = 0xff;
} else if(d1 == 7) {
cgdata[pl][0][y++] = data[p++];
} else {
cgdata[pl][0][y++] = d1;
}
}
}
// VRAMに転送
if(extract_cg) {
for(int y = 0; y < height; y++) {
uint8 b0, b1, b2, b3, c[8];
b0 = cgdata[0][1][y] = cgdata[0][0][y];
b1 = cgdata[1][1][y] = cgdata[1][0][y];
b2 = cgdata[2][1][y] = cgdata[2][0][y];
b3 = cgdata[3][1][y] = cgdata[3][0][y];
c[0] = ((b0 >> 7) & 1) | ((b1 >> 6) & 2) | ((b2 >> 5) & 4) | ((b3 >> 4) & 8);
c[1] = ((b0 >> 6) & 1) | ((b1 >> 5) & 2) | ((b2 >> 4) & 4) | ((b3 >> 3) & 8);
c[2] = ((b0 >> 5) & 1) | ((b1 >> 4) & 2) | ((b2 >> 3) & 4) | ((b3 >> 2) & 8);
c[3] = ((b0 >> 4) & 1) | ((b1 >> 3) & 2) | ((b2 >> 2) & 4) | ((b3 >> 1) & 8);
c[4] = ((b0 >> 3) & 1) | ((b1 >> 2) & 2) | ((b2 >> 1) & 4) | ((b3 ) & 8);
c[5] = ((b0 >> 2) & 1) | ((b1 >> 1) & 2) | ((b2 ) & 4) | ((b3 << 1) & 8);
c[6] = ((b0 >> 1) & 1) | ((b1 ) & 2) | ((b2 << 1) & 4) | ((b3 << 2) & 8);
c[7] = ((b0 ) & 1) | ((b1 << 1) & 2) | ((b2 << 2) & 4) | ((b3 << 3) & 8);
uint32* dest = &vram[dest_screen][y + sy][(x + sx) * 8];
if(transparent == -1) {
for(int i = 0; i < 8; i++) {
dest[i] = c[i] | base;
}
} else {
for(int i = 0; i < 8; i++) {
if(c[i] != transparent) {
dest[i] = c[i] | base;
}
}
}
}
}
}
// 画面更新
if(dest_screen == 0 && extract_cg) {
draw_screen(sx * 8, sy, width * 8, height);
}
}
+144 -144
View File
@@ -1,144 +1,144 @@
/*
ALICE SOFT SYSTEM 1 for Win32
[ AGS - vsp2l loader ]
*/
#include "ags.h"
#include <string.h>
void AGS::load_vsp2l(uint8* data, int page, int transparent)
{
// ヘッダ取得
int sx = data[0] | (data[1] << 8);
int sy = data[2] | (data[3] << 8);
int ex = data[4] | (data[5] << 8);
int ey = data[6] | (data[7] << 8);
int width = ex - sx;
int height = ey - sy;
uint8 base = 0;//(data[9] & 0x0f) << 4;
// Jコマンドの処理
if(set_cg_dest) {
sx = cg_dest_x >> 3;
sy = cg_dest_y;
ex = sx + width;
ey = sy + height;
set_cg_dest = false;
}
// Zコマンドの処理
if(palette_bank != -1) {
base = (palette_bank & 0x0f) << 4;
}
// パレット取得
screen_palette[base + 0] = SETPALETTE16(0x0, 0x0, 0x0);
screen_palette[base + 1] = SETPALETTE16(0x0, 0x0, 0xf);
screen_palette[base + 2] = SETPALETTE16(0xf, 0x0, 0x0);
screen_palette[base + 3] = SETPALETTE16(0xf, 0x0, 0xf);
screen_palette[base + 4] = SETPALETTE16(0x0, 0xf, 0x0);
screen_palette[base + 5] = SETPALETTE16(0x0, 0xf, 0xf);
screen_palette[base + 6] = SETPALETTE16(0xf, 0xf, 0x0);
screen_palette[base + 7] = SETPALETTE16(0xf, 0xf, 0xf);
// VSP2L展開
uint8 cgdata[3][2][200], mask = 0;
int p = 0x1a;
memset(cgdata, 0, sizeof(cgdata));
for(int x = 0; x < width; x++) {
for(int pl = 0; pl < 3; pl++) {
int y = 0;
while(y < height) {
uint8 d1 = data[p++];
if(d1 == 0) {
int length = data[p++] + 1;
for(int i = 0; i < length; i++) {
cgdata[pl][0][y] = cgdata[pl][1][y];
y++;
}
} else if(d1 == 1) {
int length = data[p++] + 1;
uint8 d2 = data[p++];
for(int i = 0; i < length; i++) {
cgdata[pl][0][y++] = d2;
}
} else if(d1 == 2) {
int length = data[p++] + 1;
uint8 d2 = data[p++];
uint8 d3 = data[p++];
for(int i = 0; i < length; i++) {
cgdata[pl][0][y++] = d2;
cgdata[pl][0][y++] = d3;
}
} else if(d1 == 3) {
int length = data[p++] + 1;
for(int i = 0; i < length; i++) {
cgdata[pl][0][y] = cgdata[0][0][y] ^ mask;
y++;
}
mask = 0;
} else if(d1 == 4) {
int length = data[p++] + 1;
for(int i = 0; i < length; i++) {
cgdata[pl][0][y] = cgdata[1][0][y] ^ mask;
y++;
}
mask = 0;
} else if(d1 == 5) {
int length = data[p++] + 1;
for(int i = 0; i < length; i++) {
cgdata[pl][0][y] = cgdata[2][0][y] ^ mask;
y++;
}
mask = 0;
} else if(d1 == 6) {
mask = 0xff;
} else if(d1 == 7) {
cgdata[pl][0][y++] = data[p++];
} else {
cgdata[pl][0][y++] = d1;
}
}
}
// VRAMに転送
if(extract_cg) {
for(int y = 0; y < height; y++) {
uint8 b0, b1, b2, c[8];
b0 = cgdata[0][1][y] = cgdata[0][0][y];
b1 = cgdata[1][1][y] = cgdata[1][0][y];
b2 = cgdata[2][1][y] = cgdata[2][0][y];
c[0] = ((b0 >> 7) & 1) | ((b1 >> 6) & 2) | ((b2 >> 5) & 4);
c[1] = ((b0 >> 6) & 1) | ((b1 >> 5) & 2) | ((b2 >> 4) & 4);
c[2] = ((b0 >> 5) & 1) | ((b1 >> 4) & 2) | ((b2 >> 3) & 4);
c[3] = ((b0 >> 4) & 1) | ((b1 >> 3) & 2) | ((b2 >> 2) & 4);
c[4] = ((b0 >> 3) & 1) | ((b1 >> 2) & 2) | ((b2 >> 1) & 4);
c[5] = ((b0 >> 2) & 1) | ((b1 >> 1) & 2) | ((b2 ) & 4);
c[6] = ((b0 >> 1) & 1) | ((b1 ) & 2) | ((b2 << 1) & 4);
c[7] = ((b0 ) & 1) | ((b1 << 1) & 2) | ((b2 << 2) & 4);
uint32* dest0 = &vram[dest_screen][(y + sy) * 2 + 0][(x + sx) * 8];
uint32* dest1 = &vram[dest_screen][(y + sy) * 2 + 1][(x + sx) * 8];
if(transparent == -1) {
for(int i = 0; i < 8; i++) {
dest0[i] = dest1[i] = c[i] | base;
}
} else {
for(int i = 0; i < 8; i++) {
if(c[i] != transparent) {
dest0[i] = dest1[i] = c[i] | base;
}
}
}
}
}
}
// 画面更新
if(dest_screen == 0 && extract_cg) {
draw_screen(sx * 8, sy * 2, width * 8, height * 2);
}
}
/*
ALICE SOFT SYSTEM 1 for Win32
[ AGS - vsp2l loader ]
*/
#include "ags.h"
#include <string.h>
void AGS::load_vsp2l(uint8* data, int page, int transparent)
{
// ヘッダ取得
int sx = data[0] | (data[1] << 8);
int sy = data[2] | (data[3] << 8);
int ex = data[4] | (data[5] << 8);
int ey = data[6] | (data[7] << 8);
int width = ex - sx;
int height = ey - sy;
uint8 base = 0;//(data[9] & 0x0f) << 4;
// Jコマンドの処理
if(set_cg_dest) {
sx = cg_dest_x >> 3;
sy = cg_dest_y;
ex = sx + width;
ey = sy + height;
set_cg_dest = false;
}
// Zコマンドの処理
if(palette_bank != -1) {
base = (palette_bank & 0x0f) << 4;
}
// パレット取得
screen_palette[base + 0] = SETPALETTE16(0x0, 0x0, 0x0);
screen_palette[base + 1] = SETPALETTE16(0x0, 0x0, 0xf);
screen_palette[base + 2] = SETPALETTE16(0xf, 0x0, 0x0);
screen_palette[base + 3] = SETPALETTE16(0xf, 0x0, 0xf);
screen_palette[base + 4] = SETPALETTE16(0x0, 0xf, 0x0);
screen_palette[base + 5] = SETPALETTE16(0x0, 0xf, 0xf);
screen_palette[base + 6] = SETPALETTE16(0xf, 0xf, 0x0);
screen_palette[base + 7] = SETPALETTE16(0xf, 0xf, 0xf);
// VSP2L展開
uint8 cgdata[3][2][200], mask = 0;
int p = 0x1a;
memset(cgdata, 0, sizeof(cgdata));
for(int x = 0; x < width; x++) {
for(int pl = 0; pl < 3; pl++) {
int y = 0;
while(y < height) {
uint8 d1 = data[p++];
if(d1 == 0) {
int length = data[p++] + 1;
for(int i = 0; i < length; i++) {
cgdata[pl][0][y] = cgdata[pl][1][y];
y++;
}
} else if(d1 == 1) {
int length = data[p++] + 1;
uint8 d2 = data[p++];
for(int i = 0; i < length; i++) {
cgdata[pl][0][y++] = d2;
}
} else if(d1 == 2) {
int length = data[p++] + 1;
uint8 d2 = data[p++];
uint8 d3 = data[p++];
for(int i = 0; i < length; i++) {
cgdata[pl][0][y++] = d2;
cgdata[pl][0][y++] = d3;
}
} else if(d1 == 3) {
int length = data[p++] + 1;
for(int i = 0; i < length; i++) {
cgdata[pl][0][y] = cgdata[0][0][y] ^ mask;
y++;
}
mask = 0;
} else if(d1 == 4) {
int length = data[p++] + 1;
for(int i = 0; i < length; i++) {
cgdata[pl][0][y] = cgdata[1][0][y] ^ mask;
y++;
}
mask = 0;
} else if(d1 == 5) {
int length = data[p++] + 1;
for(int i = 0; i < length; i++) {
cgdata[pl][0][y] = cgdata[2][0][y] ^ mask;
y++;
}
mask = 0;
} else if(d1 == 6) {
mask = 0xff;
} else if(d1 == 7) {
cgdata[pl][0][y++] = data[p++];
} else {
cgdata[pl][0][y++] = d1;
}
}
}
// VRAMに転送
if(extract_cg) {
for(int y = 0; y < height; y++) {
uint8 b0, b1, b2, c[8];
b0 = cgdata[0][1][y] = cgdata[0][0][y];
b1 = cgdata[1][1][y] = cgdata[1][0][y];
b2 = cgdata[2][1][y] = cgdata[2][0][y];
c[0] = ((b0 >> 7) & 1) | ((b1 >> 6) & 2) | ((b2 >> 5) & 4);
c[1] = ((b0 >> 6) & 1) | ((b1 >> 5) & 2) | ((b2 >> 4) & 4);
c[2] = ((b0 >> 5) & 1) | ((b1 >> 4) & 2) | ((b2 >> 3) & 4);
c[3] = ((b0 >> 4) & 1) | ((b1 >> 3) & 2) | ((b2 >> 2) & 4);
c[4] = ((b0 >> 3) & 1) | ((b1 >> 2) & 2) | ((b2 >> 1) & 4);
c[5] = ((b0 >> 2) & 1) | ((b1 >> 1) & 2) | ((b2 ) & 4);
c[6] = ((b0 >> 1) & 1) | ((b1 ) & 2) | ((b2 << 1) & 4);
c[7] = ((b0 ) & 1) | ((b1 << 1) & 2) | ((b2 << 2) & 4);
uint32* dest0 = &vram[dest_screen][(y + sy) * 2 + 0][(x + sx) * 8];
uint32* dest1 = &vram[dest_screen][(y + sy) * 2 + 1][(x + sx) * 8];
if(transparent == -1) {
for(int i = 0; i < 8; i++) {
dest0[i] = dest1[i] = c[i] | base;
}
} else {
for(int i = 0; i < 8; i++) {
if(c[i] != transparent) {
dest0[i] = dest1[i] = c[i] | base;
}
}
}
}
}
}
// 画面更新
if(dest_screen == 0 && extract_cg) {
draw_screen(sx * 8, sy * 2, width * 8, height * 2);
}
}
+331 -331
View File
@@ -1,331 +1,331 @@
/*
ALICE SOFT SYSTEM 3 for Win32
[ AGS - window ]
*/
#include "ags.h"
#include <string.h>
void AGS::clear_text_window(int index, bool erase)
{
int sx = text_w[index - 1].sx;
int sy = text_w[index - 1].sy;
int ex = text_w[index - 1].ex;
int ey = text_w[index - 1].ey;
if(erase) {
if(text_w[index - 1].frame && fade_level) {
draw_window(sx - 8, sy - 8, ex + 8, ey + 8, true, text_frame_color, text_back_color);
} else {
box_fill(0, sx, sy, ex, ey, text_back_color);
}
}
text_dest_x = sx;
text_dest_y = sy + 2;//text_space;
text_font_maxsize = 0;
}
bool AGS::return_text_line(int index)
{
int sx = text_w[index - 1].sx;
int ey = text_w[index - 1].ey;
text_dest_x = sx;
text_dest_y += (text_font_maxsize > text_font_size) ? text_font_maxsize : text_font_size;
text_dest_y += text_space;
text_font_maxsize = 0;
// 次の行が表示しきれるか?
return (text_dest_y + text_font_size) > ey ? true : false;
}
void AGS::draw_push(int index)
{
// Pushのパターンデータ
static uint16 pattern[16] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xe000,
0x9000, 0x9974, 0xe944, 0x8977, 0x8915, 0x8775, 0x0000, 0xffff
};
int x = text_w[index - 1].ex - 16;
int y = text_w[index - 1].ey - 16;
for(int i = 0; i < 16; i++) {
if(pattern[i] & 0x8000) vram[0][y + i][x + 0] = text_font_color;
if(pattern[i] & 0x4000) vram[0][y + i][x + 1] = text_font_color;
if(pattern[i] & 0x2000) vram[0][y + i][x + 2] = text_font_color;
if(pattern[i] & 0x1000) vram[0][y + i][x + 3] = text_font_color;
if(pattern[i] & 0x0800) vram[0][y + i][x + 4] = text_font_color;
if(pattern[i] & 0x0400) vram[0][y + i][x + 5] = text_font_color;
if(pattern[i] & 0x0200) vram[0][y + i][x + 6] = text_font_color;
if(pattern[i] & 0x0100) vram[0][y + i][x + 7] = text_font_color;
if(pattern[i] & 0x0080) vram[0][y + i][x + 8] = text_font_color;
if(pattern[i] & 0x0040) vram[0][y + i][x + 9] = text_font_color;
if(pattern[i] & 0x0020) vram[0][y + i][x + 10] = text_font_color;
if(pattern[i] & 0x0010) vram[0][y + i][x + 11] = text_font_color;
if(pattern[i] & 0x0008) vram[0][y + i][x + 12] = text_font_color;
if(pattern[i] & 0x0004) vram[0][y + i][x + 13] = text_font_color;
if(pattern[i] & 0x0002) vram[0][y + i][x + 14] = text_font_color;
if(pattern[i] & 0x0001) vram[0][y + i][x + 15] = text_font_color;
}
draw_screen(x, y, 16, 16);
}
void AGS::open_text_window(int index, bool erase)
{
int sx = text_w[index - 1].sx - (text_w[index - 1].frame ? 8 : 0);
int sy = text_w[index - 1].sy - (text_w[index - 1].frame ? 8 : 0);
int ex = text_w[index - 1].ex + (text_w[index - 1].frame ? 8 : 0);
int ey = text_w[index - 1].ey + (text_w[index - 1].frame ? 8 : 0);
int width = ex - sx + 1;
int height = ey - sy + 1;
// 画面退避
if(text_w[index - 1].push) {
if(text_w[index - 1].screen) {
free(text_w[index - 1].screen);
}
text_w[index - 1].screen = (uint32*)malloc(width * height * sizeof(uint32));
text_w[index - 1].screen_x = sx;
text_w[index - 1].screen_y = sy;
text_w[index - 1].screen_width = width;
text_w[index - 1].screen_height = height;
for(int y = 0; y < height && y + sy < 480; y++) {
uint32* scr = surface_line(hBmpDest, y + sy) + sx;
for(int x = 0; x < width && x + sx < 640; x++) {
uint32 col = vram[0][y + sy][x + sx];
if(!(col & 0x80000000)) {
text_w[index - 1].screen_palette[col & 0xff] = scr[x];
}
text_w[index - 1].screen[x + width * y] = col;
}
}
}
if(erase) {
// 窓初期化
draw_window(sx, sy, ex, ey, text_w[index - 1].frame, text_frame_color, text_back_color);
} else if(text_w[index - 1].push && text_w[index - 1].window) {
// 窓復帰
sx = text_w[index - 1].window_x;
sy = text_w[index - 1].window_y;
width = text_w[index - 1].window_width;
height = text_w[index - 1].window_height;
for(int y = 0; y < height && y + sy < 480; y++) {
for(int x = 0; x < width && x + sx < 640; x++) {
vram[0][y + sy][x + sx] = text_w[index - 1].window[x + width * y];
}
}
uint32 palette[256];
memcpy(palette, screen_palette, sizeof(screen_palette));
memcpy(screen_palette, text_w[index - 1].window_palette, sizeof(screen_palette));
draw_screen(sx, sy, width, height);
memcpy(screen_palette, palette, sizeof(screen_palette));
}
// テキスト描画位置更新
text_dest_x = text_w[index - 1].sx;
text_dest_y = text_w[index - 1].sy + text_space;;
text_font_maxsize = 0;
}
void AGS::close_text_window(int index, bool update)
{
int sx = text_w[index - 1].sx - (text_w[index - 1].frame ? 8 : 0);
int sy = text_w[index - 1].sy - (text_w[index - 1].frame ? 8 : 0);
int ex = text_w[index - 1].ex + (text_w[index - 1].frame ? 8 : 0);
int ey = text_w[index - 1].ey + (text_w[index - 1].frame ? 8 : 0);
int width = ex - sx + 1;
int height = ey - sy + 1;
// 窓退避
if(text_w[index - 1].push) {
if(text_w[index - 1].window) {
free(text_w[index - 1].window);
}
text_w[index - 1].window = (uint32*)malloc(width * height * sizeof(uint32));
text_w[index - 1].window_x = sx;
text_w[index - 1].window_y = sy;
text_w[index - 1].window_width = width;
text_w[index - 1].window_height = height;
for(int y = 0; y < height && y + sy < 480; y++) {
uint32* scr = surface_line(hBmpDest, y + sy) + sx;
for(int x = 0; x < width && x + sx < 640; x++) {
uint32 col = vram[0][y + sy][x + sx];
if(!(col & 0x80000000)) {
text_w[index - 1].window_palette[col & 0xff] = scr[x];
}
text_w[index - 1].window[x + width * y] = col;
}
}
}
// 画面復帰
if(text_w[index - 1].push && text_w[index - 1].screen) {
sx = text_w[index - 1].screen_x;
sy = text_w[index - 1].screen_y;
width = text_w[index - 1].screen_width;
height = text_w[index - 1].screen_height;
for(int y = 0; y < height && y + sy < 480; y++) {
for(int x = 0; x < width && x + sx < 640; x++) {
vram[0][y + sy][x + sx] = text_w[index - 1].screen[x + width * y];
}
}
uint32 palette[256];
memcpy(palette, screen_palette, sizeof(screen_palette));
memcpy(screen_palette, text_w[index - 1].screen_palette, sizeof(screen_palette));
draw_screen(sx, sy, width, height);
memcpy(screen_palette, palette, sizeof(screen_palette));
}
// テキスト描画位置更新
if(update) {
text_dest_x = text_w[index - 1].sx;
text_dest_y = text_w[index - 1].sy + text_space;;
text_font_maxsize = 0;
}
}
void AGS::clear_menu_window()
{
// TODO: use draw function
memset(hBmpScreen[2]->pixels, menu_back_color, 640 * 480 * sizeof(Uint32));
}
void AGS::open_menu_window(int index)
{
int sx = menu_w[index - 1].sx;
int sy = menu_w[index - 1].sy;
int ex = menu_w[index - 1].ex;
int ey = menu_fix ? menu_w[index - 1].ey : sy + menu_dest_y - 1;
int width = ex - sx + 1;
int height = ey - sy + 1;
int wsx = sx - (menu_w[index - 1].frame ? 8 : 0);
int wsy = sy - (menu_w[index - 1].frame ? 8 : 0);
int wex = ex + (menu_w[index - 1].frame ? 8 : 0);
int wey = ey + (menu_w[index - 1].frame ? 8 : 0);
int wwidth = wex - wsx + 1;
int wheight = wey - wsy + 1;
// 画面退避
if(menu_w[index - 1].push) {
if(menu_w[index - 1].screen) {
free(menu_w[index - 1].screen);
}
menu_w[index - 1].screen = (uint32*)malloc(wwidth * wheight * sizeof(uint32));
menu_w[index - 1].screen_x = wsx;
menu_w[index - 1].screen_y = wsy;
menu_w[index - 1].screen_width = wwidth;
menu_w[index - 1].screen_height = wheight;
for(int y = 0; y < wheight && y + wsy < 480; y++) {
uint32* scr = surface_line(hBmpDest, y + wsy) + wsx;
for(int x = 0; x < wwidth && x + wsx < 640; x++) {
uint32 col = vram[0][y + wsy][x + wsx];
if(!(col & 0x80000000)) {
menu_w[index - 1].screen_palette[col & 0xff] = scr[x];
}
menu_w[index - 1].screen[x + wwidth * y] = col;
}
}
}
// メニュー表示
draw_window(wsx, wsy, wex, wey, menu_w[index - 1].frame, menu_frame_color, menu_back_color);
for(int y = 0; y < height && y + sy < 480; y++) {
for(int x = 0; x < width && x + sx < 640; x++) {
vram[0][y + sy][x + sx] = vram[2][y][x];
}
}
box_line(0, sx, sy, ex, sy + menu_font_size + 3, menu_frame_color);
draw_screen(wsx, wsy, wwidth, wheight);
}
void AGS::redraw_menu_window(int index, int selected)
{
int sx = menu_w[index - 1].sx;
int sy = menu_w[index - 1].sy;
int ex = menu_w[index - 1].ex;
int ey = menu_fix ? menu_w[index - 1].ey : sy + menu_dest_y - 1;
int width = ex - sx + 1;
int height = ey - sy + 1;
for(int y = 0; y < height && y + sy < 480; y++) {
for(int x = 0; x < width && x + sx < 640; x++) {
vram[0][y + sy][x + sx] = vram[2][y][x];
}
}
box_line(0, sx, sy + (menu_font_size + 4) * selected, ex, sy + (menu_font_size + 4) * (selected + 1) - 1, menu_frame_color);
draw_screen(sx, sy, width, height);
}
void AGS::close_menu_window(int index)
{
// 画面復帰
if(menu_w[index - 1].push && menu_w[index - 1].screen) {
int sx = menu_w[index - 1].screen_x;
int sy = menu_w[index - 1].screen_y;
int width = menu_w[index - 1].screen_width;
int height = menu_w[index - 1].screen_height;
for(int y = 0; y < height && y + sy < 480; y++) {
for(int x = 0; x < width && x + sx < 640; x++) {
vram[0][y + sy][x + sx] = menu_w[index - 1].screen[x + width * y];
}
}
uint32 palette[256];
memcpy(palette, screen_palette, sizeof(screen_palette));
memcpy(screen_palette, menu_w[index - 1].screen_palette, sizeof(screen_palette));
draw_screen(sx, sy, width, height);
memcpy(screen_palette, palette, sizeof(screen_palette));
}
}
void AGS::draw_window(int sx, int sy, int ex, int ey, bool frame, uint8 frame_color, uint8 back_color)
{
// 領域の塗り潰し
for(int y = sy; y <= ey && y < 480; y++) {
uint32* dest = vram[0][y];
for(int x = sx; x <= ex && x < 640; x++) {
dest[x] = back_color;
}
}
// 枠表示
if(frame) {
for(int x = sx + 1; x <= ex - 1; x++) {
vram[0][sy + 1][x] = frame_color;
vram[0][sy + 2][x] = frame_color;
vram[0][ey - 2][x] = frame_color;
vram[0][ey - 1][x] = frame_color;
}
for(int y = sy + 1; y <= ey - 1; y++) {
vram[0][y][sx + 1] = frame_color;
vram[0][y][sx + 2] = frame_color;
vram[0][y][ex - 2] = frame_color;
vram[0][y][ex - 1] = frame_color;
}
for(int x = sx + 4; x <= ex - 4; x++) {
vram[0][sy + 4][x] = frame_color;
vram[0][ey - 4][x] = frame_color;
}
for(int y = sy + 4; y <= ey - 4; y++) {
vram[0][y][sx + 4] = frame_color;
vram[0][y][ex - 4] = frame_color;
}
}
draw_screen(sx, sy, ex - sx + 1, ey - sy + 1);
}
/*
ALICE SOFT SYSTEM 3 for Win32
[ AGS - window ]
*/
#include "ags.h"
#include <string.h>
void AGS::clear_text_window(int index, bool erase)
{
int sx = text_w[index - 1].sx;
int sy = text_w[index - 1].sy;
int ex = text_w[index - 1].ex;
int ey = text_w[index - 1].ey;
if(erase) {
if(text_w[index - 1].frame && fade_level) {
draw_window(sx - 8, sy - 8, ex + 8, ey + 8, true, text_frame_color, text_back_color);
} else {
box_fill(0, sx, sy, ex, ey, text_back_color);
}
}
text_dest_x = sx;
text_dest_y = sy + 2;//text_space;
text_font_maxsize = 0;
}
bool AGS::return_text_line(int index)
{
int sx = text_w[index - 1].sx;
int ey = text_w[index - 1].ey;
text_dest_x = sx;
text_dest_y += (text_font_maxsize > text_font_size) ? text_font_maxsize : text_font_size;
text_dest_y += text_space;
text_font_maxsize = 0;
// 次の行が表示しきれるか?
return (text_dest_y + text_font_size) > ey ? true : false;
}
void AGS::draw_push(int index)
{
// Pushのパターンデータ
static uint16 pattern[16] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xe000,
0x9000, 0x9974, 0xe944, 0x8977, 0x8915, 0x8775, 0x0000, 0xffff
};
int x = text_w[index - 1].ex - 16;
int y = text_w[index - 1].ey - 16;
for(int i = 0; i < 16; i++) {
if(pattern[i] & 0x8000) vram[0][y + i][x + 0] = text_font_color;
if(pattern[i] & 0x4000) vram[0][y + i][x + 1] = text_font_color;
if(pattern[i] & 0x2000) vram[0][y + i][x + 2] = text_font_color;
if(pattern[i] & 0x1000) vram[0][y + i][x + 3] = text_font_color;
if(pattern[i] & 0x0800) vram[0][y + i][x + 4] = text_font_color;
if(pattern[i] & 0x0400) vram[0][y + i][x + 5] = text_font_color;
if(pattern[i] & 0x0200) vram[0][y + i][x + 6] = text_font_color;
if(pattern[i] & 0x0100) vram[0][y + i][x + 7] = text_font_color;
if(pattern[i] & 0x0080) vram[0][y + i][x + 8] = text_font_color;
if(pattern[i] & 0x0040) vram[0][y + i][x + 9] = text_font_color;
if(pattern[i] & 0x0020) vram[0][y + i][x + 10] = text_font_color;
if(pattern[i] & 0x0010) vram[0][y + i][x + 11] = text_font_color;
if(pattern[i] & 0x0008) vram[0][y + i][x + 12] = text_font_color;
if(pattern[i] & 0x0004) vram[0][y + i][x + 13] = text_font_color;
if(pattern[i] & 0x0002) vram[0][y + i][x + 14] = text_font_color;
if(pattern[i] & 0x0001) vram[0][y + i][x + 15] = text_font_color;
}
draw_screen(x, y, 16, 16);
}
void AGS::open_text_window(int index, bool erase)
{
int sx = text_w[index - 1].sx - (text_w[index - 1].frame ? 8 : 0);
int sy = text_w[index - 1].sy - (text_w[index - 1].frame ? 8 : 0);
int ex = text_w[index - 1].ex + (text_w[index - 1].frame ? 8 : 0);
int ey = text_w[index - 1].ey + (text_w[index - 1].frame ? 8 : 0);
int width = ex - sx + 1;
int height = ey - sy + 1;
// 画面退避
if(text_w[index - 1].push) {
if(text_w[index - 1].screen) {
free(text_w[index - 1].screen);
}
text_w[index - 1].screen = (uint32*)malloc(width * height * sizeof(uint32));
text_w[index - 1].screen_x = sx;
text_w[index - 1].screen_y = sy;
text_w[index - 1].screen_width = width;
text_w[index - 1].screen_height = height;
for(int y = 0; y < height && y + sy < 480; y++) {
uint32* scr = surface_line(hBmpDest, y + sy) + sx;
for(int x = 0; x < width && x + sx < 640; x++) {
uint32 col = vram[0][y + sy][x + sx];
if(!(col & 0x80000000)) {
text_w[index - 1].screen_palette[col & 0xff] = scr[x];
}
text_w[index - 1].screen[x + width * y] = col;
}
}
}
if(erase) {
// 窓初期化
draw_window(sx, sy, ex, ey, text_w[index - 1].frame, text_frame_color, text_back_color);
} else if(text_w[index - 1].push && text_w[index - 1].window) {
// 窓復帰
sx = text_w[index - 1].window_x;
sy = text_w[index - 1].window_y;
width = text_w[index - 1].window_width;
height = text_w[index - 1].window_height;
for(int y = 0; y < height && y + sy < 480; y++) {
for(int x = 0; x < width && x + sx < 640; x++) {
vram[0][y + sy][x + sx] = text_w[index - 1].window[x + width * y];
}
}
uint32 palette[256];
memcpy(palette, screen_palette, sizeof(screen_palette));
memcpy(screen_palette, text_w[index - 1].window_palette, sizeof(screen_palette));
draw_screen(sx, sy, width, height);
memcpy(screen_palette, palette, sizeof(screen_palette));
}
// テキスト描画位置更新
text_dest_x = text_w[index - 1].sx;
text_dest_y = text_w[index - 1].sy + text_space;;
text_font_maxsize = 0;
}
void AGS::close_text_window(int index, bool update)
{
int sx = text_w[index - 1].sx - (text_w[index - 1].frame ? 8 : 0);
int sy = text_w[index - 1].sy - (text_w[index - 1].frame ? 8 : 0);
int ex = text_w[index - 1].ex + (text_w[index - 1].frame ? 8 : 0);
int ey = text_w[index - 1].ey + (text_w[index - 1].frame ? 8 : 0);
int width = ex - sx + 1;
int height = ey - sy + 1;
// 窓退避
if(text_w[index - 1].push) {
if(text_w[index - 1].window) {
free(text_w[index - 1].window);
}
text_w[index - 1].window = (uint32*)malloc(width * height * sizeof(uint32));
text_w[index - 1].window_x = sx;
text_w[index - 1].window_y = sy;
text_w[index - 1].window_width = width;
text_w[index - 1].window_height = height;
for(int y = 0; y < height && y + sy < 480; y++) {
uint32* scr = surface_line(hBmpDest, y + sy) + sx;
for(int x = 0; x < width && x + sx < 640; x++) {
uint32 col = vram[0][y + sy][x + sx];
if(!(col & 0x80000000)) {
text_w[index - 1].window_palette[col & 0xff] = scr[x];
}
text_w[index - 1].window[x + width * y] = col;
}
}
}
// 画面復帰
if(text_w[index - 1].push && text_w[index - 1].screen) {
sx = text_w[index - 1].screen_x;
sy = text_w[index - 1].screen_y;
width = text_w[index - 1].screen_width;
height = text_w[index - 1].screen_height;
for(int y = 0; y < height && y + sy < 480; y++) {
for(int x = 0; x < width && x + sx < 640; x++) {
vram[0][y + sy][x + sx] = text_w[index - 1].screen[x + width * y];
}
}
uint32 palette[256];
memcpy(palette, screen_palette, sizeof(screen_palette));
memcpy(screen_palette, text_w[index - 1].screen_palette, sizeof(screen_palette));
draw_screen(sx, sy, width, height);
memcpy(screen_palette, palette, sizeof(screen_palette));
}
// テキスト描画位置更新
if(update) {
text_dest_x = text_w[index - 1].sx;
text_dest_y = text_w[index - 1].sy + text_space;;
text_font_maxsize = 0;
}
}
void AGS::clear_menu_window()
{
// TODO: use draw function
memset(hBmpScreen[2]->pixels, menu_back_color, 640 * 480 * sizeof(Uint32));
}
void AGS::open_menu_window(int index)
{
int sx = menu_w[index - 1].sx;
int sy = menu_w[index - 1].sy;
int ex = menu_w[index - 1].ex;
int ey = menu_fix ? menu_w[index - 1].ey : sy + menu_dest_y - 1;
int width = ex - sx + 1;
int height = ey - sy + 1;
int wsx = sx - (menu_w[index - 1].frame ? 8 : 0);
int wsy = sy - (menu_w[index - 1].frame ? 8 : 0);
int wex = ex + (menu_w[index - 1].frame ? 8 : 0);
int wey = ey + (menu_w[index - 1].frame ? 8 : 0);
int wwidth = wex - wsx + 1;
int wheight = wey - wsy + 1;
// 画面退避
if(menu_w[index - 1].push) {
if(menu_w[index - 1].screen) {
free(menu_w[index - 1].screen);
}
menu_w[index - 1].screen = (uint32*)malloc(wwidth * wheight * sizeof(uint32));
menu_w[index - 1].screen_x = wsx;
menu_w[index - 1].screen_y = wsy;
menu_w[index - 1].screen_width = wwidth;
menu_w[index - 1].screen_height = wheight;
for(int y = 0; y < wheight && y + wsy < 480; y++) {
uint32* scr = surface_line(hBmpDest, y + wsy) + wsx;
for(int x = 0; x < wwidth && x + wsx < 640; x++) {
uint32 col = vram[0][y + wsy][x + wsx];
if(!(col & 0x80000000)) {
menu_w[index - 1].screen_palette[col & 0xff] = scr[x];
}
menu_w[index - 1].screen[x + wwidth * y] = col;
}
}
}
// メニュー表示
draw_window(wsx, wsy, wex, wey, menu_w[index - 1].frame, menu_frame_color, menu_back_color);
for(int y = 0; y < height && y + sy < 480; y++) {
for(int x = 0; x < width && x + sx < 640; x++) {
vram[0][y + sy][x + sx] = vram[2][y][x];
}
}
box_line(0, sx, sy, ex, sy + menu_font_size + 3, menu_frame_color);
draw_screen(wsx, wsy, wwidth, wheight);
}
void AGS::redraw_menu_window(int index, int selected)
{
int sx = menu_w[index - 1].sx;
int sy = menu_w[index - 1].sy;
int ex = menu_w[index - 1].ex;
int ey = menu_fix ? menu_w[index - 1].ey : sy + menu_dest_y - 1;
int width = ex - sx + 1;
int height = ey - sy + 1;
for(int y = 0; y < height && y + sy < 480; y++) {
for(int x = 0; x < width && x + sx < 640; x++) {
vram[0][y + sy][x + sx] = vram[2][y][x];
}
}
box_line(0, sx, sy + (menu_font_size + 4) * selected, ex, sy + (menu_font_size + 4) * (selected + 1) - 1, menu_frame_color);
draw_screen(sx, sy, width, height);
}
void AGS::close_menu_window(int index)
{
// 画面復帰
if(menu_w[index - 1].push && menu_w[index - 1].screen) {
int sx = menu_w[index - 1].screen_x;
int sy = menu_w[index - 1].screen_y;
int width = menu_w[index - 1].screen_width;
int height = menu_w[index - 1].screen_height;
for(int y = 0; y < height && y + sy < 480; y++) {
for(int x = 0; x < width && x + sx < 640; x++) {
vram[0][y + sy][x + sx] = menu_w[index - 1].screen[x + width * y];
}
}
uint32 palette[256];
memcpy(palette, screen_palette, sizeof(screen_palette));
memcpy(screen_palette, menu_w[index - 1].screen_palette, sizeof(screen_palette));
draw_screen(sx, sy, width, height);
memcpy(screen_palette, palette, sizeof(screen_palette));
}
}
void AGS::draw_window(int sx, int sy, int ex, int ey, bool frame, uint8 frame_color, uint8 back_color)
{
// 領域の塗り潰し
for(int y = sy; y <= ey && y < 480; y++) {
uint32* dest = vram[0][y];
for(int x = sx; x <= ex && x < 640; x++) {
dest[x] = back_color;
}
}
// 枠表示
if(frame) {
for(int x = sx + 1; x <= ex - 1; x++) {
vram[0][sy + 1][x] = frame_color;
vram[0][sy + 2][x] = frame_color;
vram[0][ey - 2][x] = frame_color;
vram[0][ey - 1][x] = frame_color;
}
for(int y = sy + 1; y <= ey - 1; y++) {
vram[0][y][sx + 1] = frame_color;
vram[0][y][sx + 2] = frame_color;
vram[0][y][ex - 2] = frame_color;
vram[0][y][ex - 1] = frame_color;
}
for(int x = sx + 4; x <= ex - 4; x++) {
vram[0][sy + 4][x] = frame_color;
vram[0][ey - 4][x] = frame_color;
}
for(int y = sy + 4; y <= ey - 4; y++) {
vram[0][y][sx + 4] = frame_color;
vram[0][y][ex - 4] = frame_color;
}
}
draw_screen(sx, sy, ex - sx + 1, ey - sy + 1);
}
+79 -79
View File
@@ -1,79 +1,79 @@
/*
ALICE SOFT SYSTEM 3 for Win32
[ crc32 database ]
*/
#ifndef _CRC32_H_
#define _CRC32_H_
// ADISK.DATの先頭256bytes
// SYSTEM1
#define CRC32_BUNKASAI 0xc80f99b8 // あぶない文化祭前夜
#define CRC32_CRESCENT 0x42351f2c // クレセントムーンがぁる
#define CRC32_DPS 0x69ea4865 // D.P.S. - Dream Program System
#define CRC32_DPS_SG 0xab4cda48 // D.P.S. SG
#define CRC32_DPS_SG_FAHREN 0xe405d57c // D.P.S. SG - Fahren Fliegen
#define CRC32_DPS_SG_KATEI 0x23e67d18 // D.P.S. SG - 家庭教師はステキなお仕事
#define CRC32_DPS_SG_NOBUNAGA 0x2ec116f2 // D.P.S. SG - 信長の淫謀
#define CRC32_DPS_SG2 0xab4cda48 // D.P.S. SG set2
#define CRC32_DPS_SG2_ANTIQUE 0x41fe8b3d // D.P.S. SG set2 - ANTIQUE HOUSE
#define CRC32_DPS_SG2_IKENAI 0x6b562c09 // D.P.S. SG set2 - いけない内科検診再び
#define CRC32_DPS_SG2_AKAI 0x1098e78c // D.P.S. SG set2 - 朱い夜
#define CRC32_DPS_SG3 0xb77ae133 // D.P.S. SG SG set3
#define CRC32_DPS_SG3_RABBIT 0xa3228b6c // D.P.S. SG set3 - Rabbit P4P
#define CRC32_DPS_SG3_SHINKON 0x09b4448a // D.P.S. SG set3 - しんこんさんものがたり
#define CRC32_DPS_SG3_SOTSUGYOU 0xbc4525d8 // D.P.S. SG set3 - 卒業
#define CRC32_FUKEI 0x026de326 // 婦警さんVX
#define CRC32_INTRUDER 0xa7520fb2 // Intruder -桜屋敷の探索-
#define CRC32_TENGU 0xc942ff58 // あぶないてんぐ伝説
#define CRC32_TOUSHIN_HINT 0xac337537 // 闘神都市 ヒントディスク
#define CRC32_VAMPIRE 0x957bcfbf // Little Vampire
#define CRC32_VAMPIRE_ENG 0x61985a7f // Little Vampire (English) Patch 1.5
#define CRC32_YAKATA 0x8cef6fa6 // ALICEの館
// SYSTEM2
#define CRC32_AYUMI_FD 0x4e2fed2a // あゆみちゃん物語 (FD)
#define CRC32_AYUMI_HINT 0xf6bd963a // あゆみちゃん物語 ヒントディスク
#define CRC32_AYUMI_PROTO 0x4e2f5678 // あゆみちゃん物語 PROTO
#define CRC32_DALK_HINT 0x4793b843 // DALK ヒントディスク
#define CRC32_DRSTOP 0x73fa86c4 // Dr. STOP!
#define CRC32_PROSTUDENTG_FD 0x5ffbfee7 // Prostudent -G- (FD)
#define CRC32_RANCE3_HINT 0x8d5ec610 // Rance3 ヒントディスク
#define CRC32_SDPS 0xc7a20cdf // Super D.P.S
#define CRC32_SDPS_MARIA 0x80d4eaca // Super D.P.S - マリアとカンパン
#define CRC32_SDPS_TONO 0xbb1edff1 // Super D.P.S - 遠野の森
#define CRC32_SDPS_KAIZOKU 0xf81829e3 // Super D.P.S - うれしたのし海賊稼業
#define CRC32_YAKATA2 0x2df591ff // ALICEの館II
// SYSTEM3
#define CRC32_AMBIVALENZ_FD 0xa6b48dfe // AmbivalenZ (FD)
#define CRC32_AMBIVALENZ_CD 0x4b10db69 // AmbivalenZ (CD)
#define CRC32_DPSALL 0xd48b4ec6 // DPS全部
#define CRC32_FUNNYBEE_CD 0xe14e3971 // Funny Bee (CD)
#define CRC32_FUNNYBEE_PATCH 0xe14e3971 // Funny Bee (CD + Patch)
#define CRC32_FUNNYBEE_FD 0x731267fa // Funny Bee (FD)
#define CRC32_ONLYYOU 0x832aeb97 // Only You
#define CRC32_ONLYYOU_DEMO 0xc1d13e44 // Only You (DEMO)
#define CRC32_PROSTUDENTG_CD 0xfb0e4a63 // Prostudent -G- (CD)
#define CRC32_PROG_OMAKE 0x8ba18bff // Prostudent G おまけ (CRC32 of AGAME.DAT)
#define CRC32_RANCE41 0xa43fb4b6 // Rance 4.1
#define CRC32_RANCE41_ENG 0x811f4ff3 // Rance 4.1 (English) 1.5 Beta
#define CRC32_RANCE42 0x04d24d1e // Rance 4.2
#define CRC32_RANCE42_ENG 0xa97cc370 // Rance 4.2 (English) 1.5 Beta
#define CRC32_AYUMI_CD 0xd2bed9ee // あゆみちゃん物語 (CD)
#define CRC32_AYUMI_JISSHA_256 0x00d15a2b // あゆみちゃん物語 実写版
#define CRC32_AYUMI_JISSHA_FULL 0x5f66ff1d // あゆみちゃん物語 フルカラー実写版
#define CRC32_YAKATA3_CD 0x7f8f5e2a // アリスの館3 (CD)
#define CRC32_YAKATA3_FD 0x58ebcc99 // アリスの館3 (FD)
#define CRC32_HASHIRIONNA2 0x09f47cbd // 走り女2 (Rance 4.x ヒントディスク)
#define CRC32_TOUSHIN2_GD 0xb5eba798 // 闘神都市2 グラフィックディスク
#define CRC32_TOUSHIN2_SP 0x2172c7b2 // 闘神都市2 そして、それから…
#define CRC32_OTOMESENKI 0x49a4db15 // 乙女戦記
#define CRC32_NINGYO 0xd491e7ab // 人魚 -蘿子-
#define CRC32_MUGENHOUYOU 0xbb27d1ba // 夢幻泡影
#endif
/*
ALICE SOFT SYSTEM 3 for Win32
[ crc32 database ]
*/
#ifndef _CRC32_H_
#define _CRC32_H_
// ADISK.DATの先頭256bytes
// SYSTEM1
#define CRC32_BUNKASAI 0xc80f99b8 // あぶない文化祭前夜
#define CRC32_CRESCENT 0x42351f2c // クレセントムーンがぁる
#define CRC32_DPS 0x69ea4865 // D.P.S. - Dream Program System
#define CRC32_DPS_SG 0xab4cda48 // D.P.S. SG
#define CRC32_DPS_SG_FAHREN 0xe405d57c // D.P.S. SG - Fahren Fliegen
#define CRC32_DPS_SG_KATEI 0x23e67d18 // D.P.S. SG - 家庭教師はステキなお仕事
#define CRC32_DPS_SG_NOBUNAGA 0x2ec116f2 // D.P.S. SG - 信長の淫謀
#define CRC32_DPS_SG2 0xab4cda48 // D.P.S. SG set2
#define CRC32_DPS_SG2_ANTIQUE 0x41fe8b3d // D.P.S. SG set2 - ANTIQUE HOUSE
#define CRC32_DPS_SG2_IKENAI 0x6b562c09 // D.P.S. SG set2 - いけない内科検診再び
#define CRC32_DPS_SG2_AKAI 0x1098e78c // D.P.S. SG set2 - 朱い夜
#define CRC32_DPS_SG3 0xb77ae133 // D.P.S. SG SG set3
#define CRC32_DPS_SG3_RABBIT 0xa3228b6c // D.P.S. SG set3 - Rabbit P4P
#define CRC32_DPS_SG3_SHINKON 0x09b4448a // D.P.S. SG set3 - しんこんさんものがたり
#define CRC32_DPS_SG3_SOTSUGYOU 0xbc4525d8 // D.P.S. SG set3 - 卒業
#define CRC32_FUKEI 0x026de326 // 婦警さんVX
#define CRC32_INTRUDER 0xa7520fb2 // Intruder -桜屋敷の探索-
#define CRC32_TENGU 0xc942ff58 // あぶないてんぐ伝説
#define CRC32_TOUSHIN_HINT 0xac337537 // 闘神都市 ヒントディスク
#define CRC32_VAMPIRE 0x957bcfbf // Little Vampire
#define CRC32_VAMPIRE_ENG 0x61985a7f // Little Vampire (English) Patch 1.5
#define CRC32_YAKATA 0x8cef6fa6 // ALICEの館
// SYSTEM2
#define CRC32_AYUMI_FD 0x4e2fed2a // あゆみちゃん物語 (FD)
#define CRC32_AYUMI_HINT 0xf6bd963a // あゆみちゃん物語 ヒントディスク
#define CRC32_AYUMI_PROTO 0x4e2f5678 // あゆみちゃん物語 PROTO
#define CRC32_DALK_HINT 0x4793b843 // DALK ヒントディスク
#define CRC32_DRSTOP 0x73fa86c4 // Dr. STOP!
#define CRC32_PROSTUDENTG_FD 0x5ffbfee7 // Prostudent -G- (FD)
#define CRC32_RANCE3_HINT 0x8d5ec610 // Rance3 ヒントディスク
#define CRC32_SDPS 0xc7a20cdf // Super D.P.S
#define CRC32_SDPS_MARIA 0x80d4eaca // Super D.P.S - マリアとカンパン
#define CRC32_SDPS_TONO 0xbb1edff1 // Super D.P.S - 遠野の森
#define CRC32_SDPS_KAIZOKU 0xf81829e3 // Super D.P.S - うれしたのし海賊稼業
#define CRC32_YAKATA2 0x2df591ff // ALICEの館II
// SYSTEM3
#define CRC32_AMBIVALENZ_FD 0xa6b48dfe // AmbivalenZ (FD)
#define CRC32_AMBIVALENZ_CD 0x4b10db69 // AmbivalenZ (CD)
#define CRC32_DPSALL 0xd48b4ec6 // DPS全部
#define CRC32_FUNNYBEE_CD 0xe14e3971 // Funny Bee (CD)
#define CRC32_FUNNYBEE_PATCH 0xe14e3971 // Funny Bee (CD + Patch)
#define CRC32_FUNNYBEE_FD 0x731267fa // Funny Bee (FD)
#define CRC32_ONLYYOU 0x832aeb97 // Only You
#define CRC32_ONLYYOU_DEMO 0xc1d13e44 // Only You (DEMO)
#define CRC32_PROSTUDENTG_CD 0xfb0e4a63 // Prostudent -G- (CD)
#define CRC32_PROG_OMAKE 0x8ba18bff // Prostudent G おまけ (CRC32 of AGAME.DAT)
#define CRC32_RANCE41 0xa43fb4b6 // Rance 4.1
#define CRC32_RANCE41_ENG 0x811f4ff3 // Rance 4.1 (English) 1.5 Beta
#define CRC32_RANCE42 0x04d24d1e // Rance 4.2
#define CRC32_RANCE42_ENG 0xa97cc370 // Rance 4.2 (English) 1.5 Beta
#define CRC32_AYUMI_CD 0xd2bed9ee // あゆみちゃん物語 (CD)
#define CRC32_AYUMI_JISSHA_256 0x00d15a2b // あゆみちゃん物語 実写版
#define CRC32_AYUMI_JISSHA_FULL 0x5f66ff1d // あゆみちゃん物語 フルカラー実写版
#define CRC32_YAKATA3_CD 0x7f8f5e2a // アリスの館3 (CD)
#define CRC32_YAKATA3_FD 0x58ebcc99 // アリスの館3 (FD)
#define CRC32_HASHIRIONNA2 0x09f47cbd // 走り女2 (Rance 4.x ヒントディスク)
#define CRC32_TOUSHIN2_GD 0xb5eba798 // 闘神都市2 グラフィックディスク
#define CRC32_TOUSHIN2_SP 0x2172c7b2 // 闘神都市2 そして、それから…
#define CRC32_OTOMESENKI 0x49a4db15 // 乙女戦記
#define CRC32_NINGYO 0xd491e7ab // 人魚 -蘿子-
#define CRC32_MUGENHOUYOU 0xbb27d1ba // 夢幻泡影
#endif
+319 -319
View File
@@ -1,319 +1,319 @@
/*
ALICE SOFT SYSTEM 3 for Win32
[ DRI ]
*/
#include "dri.h"
#include <string.h>
#include "crc32.h"
#include "../fileio.h"
uint8* DRI::load(const char* file_name, int page, int* size)
{
char tmp_name[20];
strcpy_s(tmp_name, sizeof(tmp_name), file_name);
FILEIO* fio = new FILEIO();
// ページの位置を取得
tmp_name[0] = 'A';
if(!fio->Fopen(tmp_name, FILEIO_READ_BINARY)) {
delete fio;
return NULL;
}
int link_sector = fio->Fgetc();
link_sector |= fio->Fgetc() << 8;
int data_sector = fio->Fgetc();
data_sector |= fio->Fgetc() << 8;
if(page > (data_sector - link_sector) * 128 - 1) {
// ページ番号不正
fio->Fclose();
delete fio;
return NULL;
}
fio->Fseek((link_sector - 1) * 256 + (page - 1) * 2, FILEIO_SEEK_SET);
int disk_index = fio->Fgetc();
int link_index = fio->Fgetc();
if(disk_index == 0 || disk_index == 0x1a) {
// 欠番
fio->Fclose();
delete fio;
return NULL;
}
// A??.DAT以外にリンクされている場合はファイルを開き直す
if(disk_index != 1) {
tmp_name[0] = 'A' + disk_index - 1;
fio->Fclose();
if(!fio->Fopen(tmp_name, FILEIO_READ_BINARY)) {
delete fio;
return NULL;
}
}
// データ取得
fio->Fseek(link_index * 2, FILEIO_SEEK_SET);
int start_sector = fio->Fgetc();
start_sector |= fio->Fgetc() << 8;
int end_sector = fio->Fgetc();
end_sector |= fio->Fgetc() << 8;
if((*size = (end_sector - start_sector) * 256) == 0) {
// サイズ不正
fio->Fclose();
delete fio;
return NULL;
}
uint8 *buffer = (uint8 *)malloc(*size);
fio->Fseek((start_sector - 1) * 256, FILEIO_SEEK_SET);
fio->Fread(buffer, 256, end_sector - start_sector);
fio->Fclose();
delete fio;
return buffer;
}
uint8* DRI::load_mda(uint32 crc32_a, uint32 crc32_b, int page, int* size)
{
// データ取得
const char* name = NULL;
switch(crc32_a) {
case CRC32_BUNKASAI: // あぶない文化祭前夜
name = "AMUS_AB.MDA";
break;
case CRC32_CRESCENT: // クレセントムーンがぁる
name = "AMUS_CRS.MDA";
break;
case CRC32_DPS: // D.P.S. - Dream Program System
name = "AMUS_DPS.MDA";
break;
case CRC32_DPS_SG: // D.P.S. SG
// case CRC32_DPS_SG2: // D.P.S. SG set2
case CRC32_DPS_SG3: // D.P.S. SG set2
name = "AMUS_SG.MDA";
break;
case CRC32_FUKEI: // 婦警さんVX
name = "AMUS_VX.MDA";
break;
case CRC32_INTRUDER: // Intruder -桜屋敷の探索-
name = "AMUS_INT";
break;
case CRC32_TENGU: // あぶないてんぐ伝説
name = "AMUS_AT";
break;
case CRC32_TOUSHIN_HINT: // 闘神都市 ヒントディスク
name = "AMUS_T1";
break;
case CRC32_VAMPIRE: // Little Vampire
case CRC32_VAMPIRE_ENG:
name = "AMUS_LP2";
break;
case CRC32_YAKATA: // ALICEの館
name = "AMUS_AL1";
break;
case CRC32_AYUMI_FD: // あゆみちゃん物語 (FD)
case CRC32_AYUMI_HINT: // あゆみちゃん物語 ヒントディスク
case CRC32_AYUMI_PROTO: // あゆみちゃん物語 PROTO
name = "AMUS_AYM";
break;
case CRC32_DALK_HINT: // DALK ヒントディスク
name = "AMUS_DLK";
break;
case CRC32_DRSTOP: // Dr. STOP!
name = "AMUS_DRS";
break;
case CRC32_PROSTUDENTG_FD: // Prostudent -G- (FD)
name = "AMUS_PSG";
break;
case CRC32_RANCE3_HINT: // Rance3 ヒントディスク
name = "AMUS_R3H";
break;
case CRC32_SDPS: // Super D.P.S
name = "AMUS_SDP";
break;
case CRC32_YAKATA2: // ALICEの館II
name = "AMUS_AL2";
break;
case CRC32_AMBIVALENZ_FD: // AmbivalenZ (FD)
case CRC32_AMBIVALENZ_CD: // AmbivalenZ (CD)
name = "AMUS_AMB.MDA";
break;
case CRC32_DPSALL: // DPS全部
name = "AMUS_ALL.MDA";
break;
case CRC32_FUNNYBEE_CD: // Funny Bee (CD)
// case CRC32_FUNNYBEE_PATCH: // Funny Bee (CD + Patch)
case CRC32_FUNNYBEE_FD: // Funny Bee (FD)
name = "AMUS_BEE.MDA";
break;
case CRC32_ONLYYOU: // Only You
case CRC32_ONLYYOU_DEMO: // Only You (DEMO)
name = "AMUS_OY.MDA";
break;
case CRC32_PROSTUDENTG_CD: // Prostudent -G- (CD)
name = "AMUS_PSG.MDA";
break;
case CRC32_RANCE41: // Rance 4.1
case CRC32_RANCE41_ENG:
name = "AMUS_R41.MDA";
break;
case CRC32_RANCE42: // Rance 4.2
case CRC32_RANCE42_ENG:
name = "AMUS_R42.MDA";
break;
case CRC32_AYUMI_CD: // あゆみちゃん物語 (CD)
case CRC32_AYUMI_JISSHA_256: // あゆみちゃん物語 実写版
case CRC32_AYUMI_JISSHA_FULL: // あゆみちゃん物語 フルカラー実写版
name = "AMUS_AYM.MDA";
break;
case CRC32_YAKATA3_CD: // アリスの館3 (CD)
case CRC32_YAKATA3_FD: // アリスの館3 (FD)
name = "AMUS_AL3.MDA";
break;
case CRC32_HASHIRIONNA2: // 走り女2 (Rance 4.x ヒントディスク)
name = "AMUS_RG2.MDA";
break;
case CRC32_TOUSHIN2_GD: // 闘神都市2 グラフィックディスク
name = "AMUS_T2";
break;
case CRC32_OTOMESENKI: // 乙女戦記
name = "AMUS_OTM.MDA";
break;
case CRC32_MUGENHOUYOU: // 夢幻泡影
name = "AMUS_MGN.MDA";
break;
}
if(name == NULL) {
return NULL;
}
SDL_RWops* rw = open_resource(name, "mda");
if (!rw)
return NULL;
uint8 buf[4];
// ページの位置を取得
SDL_RWread(rw, buf, 4, 1);
int link_sector = buf[0] | (buf[1] << 8);
int data_sector = buf[2] | (buf[3] << 8);
if(page > (data_sector - link_sector) * 128 - 1) {
// ページ番号不正
SDL_RWclose(rw);
return NULL;
}
SDL_RWseek(rw, (link_sector - 1) * 256 + (page - 1) * 2, RW_SEEK_SET);
SDL_RWread(rw, buf, 2, 1);
int disk_index = buf[0];
int link_index = buf[1];
if(disk_index == 0 || disk_index == 0x1a) {
// 欠番
SDL_RWclose(rw);
return NULL;
}
// AMUS.MDA以外にリンクされている場合はリソースを開き直す
if(disk_index == 2) {
SDL_RWclose(rw);
switch(crc32_b) {
case CRC32_DPS_SG_FAHREN: // D.P.S. SG - Fahren Fliegen
name = "BMUS_FAH";
break;
case CRC32_DPS_SG_KATEI: // D.P.S. SG - 家庭教師はステキなお仕事
name = "BMUS_KAT";
break;
case CRC32_DPS_SG_NOBUNAGA: // D.P.S. SG - 信長の淫謀
name = "BMUS_NOB";
break;
case CRC32_DPS_SG2_ANTIQUE: // D.P.S. SG set2 - ANTIQUE HOUSE
name = "BMUS_ANT";
break;
case CRC32_DPS_SG2_IKENAI: // D.P.S. SG set2 - いけない内科検診再び
name = "BMUS_NAI";
break;
case CRC32_DPS_SG2_AKAI: // D.P.S. SG set2 - 朱い夜
name = "BMUS_AKA";
break;
case CRC32_DPS_SG3_RABBIT: // D.P.S. SG set3 - Rabbit P4P
name = "BMUS_RAB";
break;
case CRC32_DPS_SG3_SHINKON: // D.P.S. SG set3 - しんこんさんものがたり
name = "BMUS_SIN";
break;
case CRC32_DPS_SG3_SOTSUGYOU: // D.P.S. SG set3 - 卒業
name = "BMUS_SOT";
break;
case CRC32_SDPS_MARIA: // Super D.P.S - マリアとカンパン
name = "BMUS_MTK";
break;
case CRC32_SDPS_TONO: // Super D.P.S - 遠野の森
name = "BMUS_TNM";
break;
case CRC32_SDPS_KAIZOKU: // Super D.P.S - うれしたのし海賊稼業
name = "BMUS_KAM";
break;
default:
name = NULL;
break;
}
if(name == NULL) {
return NULL;
}
if((rw = open_resource(name, "mda")) == NULL) {
return NULL;
}
} else if(disk_index == 3) {
SDL_RWclose(rw);
switch(crc32_a) {
case CRC32_TOUSHIN_HINT: // 闘神都市 ヒントディスク
name = "CMUS_T1";
break;
default:
name = NULL;
break;
}
if(name == NULL) {
return NULL;
}
if((rw = open_resource(name, "mda")) == NULL) {
return NULL;
}
} else if(disk_index != 1) {
// AMUS.MDA以外にリンクされている場合は失敗
SDL_RWclose(rw);
return NULL;
}
// データ取得
SDL_RWseek(rw, link_index * 2, RW_SEEK_SET);
SDL_RWread(rw, buf, 4, 1);
int start_sector = buf[0] | (buf[1] << 8);
int end_sector = buf[2] | (buf[3] << 8);
if((*size = (end_sector - start_sector) * 256) == 0) {
// サイズ不正
SDL_RWclose(rw);
return NULL;
}
uint8* buffer = (uint8*)malloc(*size);
SDL_RWseek(rw, (start_sector - 1) * 256, RW_SEEK_SET);
SDL_RWread(rw, buffer, *size, 1);
SDL_RWclose(rw);
return buffer;
}
/*
ALICE SOFT SYSTEM 3 for Win32
[ DRI ]
*/
#include "dri.h"
#include <string.h>
#include "crc32.h"
#include "../fileio.h"
uint8* DRI::load(const char* file_name, int page, int* size)
{
char tmp_name[20];
strcpy_s(tmp_name, sizeof(tmp_name), file_name);
FILEIO* fio = new FILEIO();
// ページの位置を取得
tmp_name[0] = 'A';
if(!fio->Fopen(tmp_name, FILEIO_READ_BINARY)) {
delete fio;
return NULL;
}
int link_sector = fio->Fgetc();
link_sector |= fio->Fgetc() << 8;
int data_sector = fio->Fgetc();
data_sector |= fio->Fgetc() << 8;
if(page > (data_sector - link_sector) * 128 - 1) {
// ページ番号不正
fio->Fclose();
delete fio;
return NULL;
}
fio->Fseek((link_sector - 1) * 256 + (page - 1) * 2, FILEIO_SEEK_SET);
int disk_index = fio->Fgetc();
int link_index = fio->Fgetc();
if(disk_index == 0 || disk_index == 0x1a) {
// 欠番
fio->Fclose();
delete fio;
return NULL;
}
// A??.DAT以外にリンクされている場合はファイルを開き直す
if(disk_index != 1) {
tmp_name[0] = 'A' + disk_index - 1;
fio->Fclose();
if(!fio->Fopen(tmp_name, FILEIO_READ_BINARY)) {
delete fio;
return NULL;
}
}
// データ取得
fio->Fseek(link_index * 2, FILEIO_SEEK_SET);
int start_sector = fio->Fgetc();
start_sector |= fio->Fgetc() << 8;
int end_sector = fio->Fgetc();
end_sector |= fio->Fgetc() << 8;
if((*size = (end_sector - start_sector) * 256) == 0) {
// サイズ不正
fio->Fclose();
delete fio;
return NULL;
}
uint8 *buffer = (uint8 *)malloc(*size);
fio->Fseek((start_sector - 1) * 256, FILEIO_SEEK_SET);
fio->Fread(buffer, 256, end_sector - start_sector);
fio->Fclose();
delete fio;
return buffer;
}
uint8* DRI::load_mda(uint32 crc32_a, uint32 crc32_b, int page, int* size)
{
// データ取得
const char* name = NULL;
switch(crc32_a) {
case CRC32_BUNKASAI: // あぶない文化祭前夜
name = "AMUS_AB.MDA";
break;
case CRC32_CRESCENT: // クレセントムーンがぁる
name = "AMUS_CRS.MDA";
break;
case CRC32_DPS: // D.P.S. - Dream Program System
name = "AMUS_DPS.MDA";
break;
case CRC32_DPS_SG: // D.P.S. SG
// case CRC32_DPS_SG2: // D.P.S. SG set2
case CRC32_DPS_SG3: // D.P.S. SG set2
name = "AMUS_SG.MDA";
break;
case CRC32_FUKEI: // 婦警さんVX
name = "AMUS_VX.MDA";
break;
case CRC32_INTRUDER: // Intruder -桜屋敷の探索-
name = "AMUS_INT";
break;
case CRC32_TENGU: // あぶないてんぐ伝説
name = "AMUS_AT";
break;
case CRC32_TOUSHIN_HINT: // 闘神都市 ヒントディスク
name = "AMUS_T1";
break;
case CRC32_VAMPIRE: // Little Vampire
case CRC32_VAMPIRE_ENG:
name = "AMUS_LP2";
break;
case CRC32_YAKATA: // ALICEの館
name = "AMUS_AL1";
break;
case CRC32_AYUMI_FD: // あゆみちゃん物語 (FD)
case CRC32_AYUMI_HINT: // あゆみちゃん物語 ヒントディスク
case CRC32_AYUMI_PROTO: // あゆみちゃん物語 PROTO
name = "AMUS_AYM";
break;
case CRC32_DALK_HINT: // DALK ヒントディスク
name = "AMUS_DLK";
break;
case CRC32_DRSTOP: // Dr. STOP!
name = "AMUS_DRS";
break;
case CRC32_PROSTUDENTG_FD: // Prostudent -G- (FD)
name = "AMUS_PSG";
break;
case CRC32_RANCE3_HINT: // Rance3 ヒントディスク
name = "AMUS_R3H";
break;
case CRC32_SDPS: // Super D.P.S
name = "AMUS_SDP";
break;
case CRC32_YAKATA2: // ALICEの館II
name = "AMUS_AL2";
break;
case CRC32_AMBIVALENZ_FD: // AmbivalenZ (FD)
case CRC32_AMBIVALENZ_CD: // AmbivalenZ (CD)
name = "AMUS_AMB.MDA";
break;
case CRC32_DPSALL: // DPS全部
name = "AMUS_ALL.MDA";
break;
case CRC32_FUNNYBEE_CD: // Funny Bee (CD)
// case CRC32_FUNNYBEE_PATCH: // Funny Bee (CD + Patch)
case CRC32_FUNNYBEE_FD: // Funny Bee (FD)
name = "AMUS_BEE.MDA";
break;
case CRC32_ONLYYOU: // Only You
case CRC32_ONLYYOU_DEMO: // Only You (DEMO)
name = "AMUS_OY.MDA";
break;
case CRC32_PROSTUDENTG_CD: // Prostudent -G- (CD)
name = "AMUS_PSG.MDA";
break;
case CRC32_RANCE41: // Rance 4.1
case CRC32_RANCE41_ENG:
name = "AMUS_R41.MDA";
break;
case CRC32_RANCE42: // Rance 4.2
case CRC32_RANCE42_ENG:
name = "AMUS_R42.MDA";
break;
case CRC32_AYUMI_CD: // あゆみちゃん物語 (CD)
case CRC32_AYUMI_JISSHA_256: // あゆみちゃん物語 実写版
case CRC32_AYUMI_JISSHA_FULL: // あゆみちゃん物語 フルカラー実写版
name = "AMUS_AYM.MDA";
break;
case CRC32_YAKATA3_CD: // アリスの館3 (CD)
case CRC32_YAKATA3_FD: // アリスの館3 (FD)
name = "AMUS_AL3.MDA";
break;
case CRC32_HASHIRIONNA2: // 走り女2 (Rance 4.x ヒントディスク)
name = "AMUS_RG2.MDA";
break;
case CRC32_TOUSHIN2_GD: // 闘神都市2 グラフィックディスク
name = "AMUS_T2";
break;
case CRC32_OTOMESENKI: // 乙女戦記
name = "AMUS_OTM.MDA";
break;
case CRC32_MUGENHOUYOU: // 夢幻泡影
name = "AMUS_MGN.MDA";
break;
}
if(name == NULL) {
return NULL;
}
SDL_RWops* rw = open_resource(name, "mda");
if (!rw)
return NULL;
uint8 buf[4];
// ページの位置を取得
SDL_RWread(rw, buf, 4, 1);
int link_sector = buf[0] | (buf[1] << 8);
int data_sector = buf[2] | (buf[3] << 8);
if(page > (data_sector - link_sector) * 128 - 1) {
// ページ番号不正
SDL_RWclose(rw);
return NULL;
}
SDL_RWseek(rw, (link_sector - 1) * 256 + (page - 1) * 2, RW_SEEK_SET);
SDL_RWread(rw, buf, 2, 1);
int disk_index = buf[0];
int link_index = buf[1];
if(disk_index == 0 || disk_index == 0x1a) {
// 欠番
SDL_RWclose(rw);
return NULL;
}
// AMUS.MDA以外にリンクされている場合はリソースを開き直す
if(disk_index == 2) {
SDL_RWclose(rw);
switch(crc32_b) {
case CRC32_DPS_SG_FAHREN: // D.P.S. SG - Fahren Fliegen
name = "BMUS_FAH";
break;
case CRC32_DPS_SG_KATEI: // D.P.S. SG - 家庭教師はステキなお仕事
name = "BMUS_KAT";
break;
case CRC32_DPS_SG_NOBUNAGA: // D.P.S. SG - 信長の淫謀
name = "BMUS_NOB";
break;
case CRC32_DPS_SG2_ANTIQUE: // D.P.S. SG set2 - ANTIQUE HOUSE
name = "BMUS_ANT";
break;
case CRC32_DPS_SG2_IKENAI: // D.P.S. SG set2 - いけない内科検診再び
name = "BMUS_NAI";
break;
case CRC32_DPS_SG2_AKAI: // D.P.S. SG set2 - 朱い夜
name = "BMUS_AKA";
break;
case CRC32_DPS_SG3_RABBIT: // D.P.S. SG set3 - Rabbit P4P
name = "BMUS_RAB";
break;
case CRC32_DPS_SG3_SHINKON: // D.P.S. SG set3 - しんこんさんものがたり
name = "BMUS_SIN";
break;
case CRC32_DPS_SG3_SOTSUGYOU: // D.P.S. SG set3 - 卒業
name = "BMUS_SOT";
break;
case CRC32_SDPS_MARIA: // Super D.P.S - マリアとカンパン
name = "BMUS_MTK";
break;
case CRC32_SDPS_TONO: // Super D.P.S - 遠野の森
name = "BMUS_TNM";
break;
case CRC32_SDPS_KAIZOKU: // Super D.P.S - うれしたのし海賊稼業
name = "BMUS_KAM";
break;
default:
name = NULL;
break;
}
if(name == NULL) {
return NULL;
}
if((rw = open_resource(name, "mda")) == NULL) {
return NULL;
}
} else if(disk_index == 3) {
SDL_RWclose(rw);
switch(crc32_a) {
case CRC32_TOUSHIN_HINT: // 闘神都市 ヒントディスク
name = "CMUS_T1";
break;
default:
name = NULL;
break;
}
if(name == NULL) {
return NULL;
}
if((rw = open_resource(name, "mda")) == NULL) {
return NULL;
}
} else if(disk_index != 1) {
// AMUS.MDA以外にリンクされている場合は失敗
SDL_RWclose(rw);
return NULL;
}
// データ取得
SDL_RWseek(rw, link_index * 2, RW_SEEK_SET);
SDL_RWread(rw, buf, 4, 1);
int start_sector = buf[0] | (buf[1] << 8);
int end_sector = buf[2] | (buf[3] << 8);
if((*size = (end_sector - start_sector) * 256) == 0) {
// サイズ不正
SDL_RWclose(rw);
return NULL;
}
uint8* buffer = (uint8*)malloc(*size);
SDL_RWseek(rw, (start_sector - 1) * 256, RW_SEEK_SET);
SDL_RWread(rw, buffer, *size, 1);
SDL_RWclose(rw);
return buffer;
}
+22 -22
View File
@@ -1,22 +1,22 @@
/*
ALICE SOFT SYSTEM 3 for Win32
[ DRI ]
*/
#ifndef _DRI_H_
#define _DRI_H_
#include "../common.h"
class DRI
{
public:
DRI() {}
~DRI() {}
uint8* load(const char* file_name, int page, int* size);
uint8* load_mda(uint32 crc32_a, uint32 crc32_b, int page, int* size);
};
#endif
/*
ALICE SOFT SYSTEM 3 for Win32
[ DRI ]
*/
#ifndef _DRI_H_
#define _DRI_H_
#include "../common.h"
class DRI
{
public:
DRI() {}
~DRI() {}
uint8* load(const char* file_name, int page, int* size);
uint8* load_mda(uint32 crc32_a, uint32 crc32_b, int page, int* size);
};
#endif
+70 -70
View File
@@ -1,70 +1,70 @@
/*
ALICE SOFT SYSTEM 3 for Win32
[ MAKO ]
*/
#ifndef _MAKO_H_
#define _MAKO_H_
#include <vector>
#include <stdio.h>
#include <limits.h>
#include <math.h>
#include "../common.h"
#include "nact.h"
enum BGMDevice {
BGM_FM,
BGM_MIDI,
BGM_CD
};
struct Config;
class MAKO
{
public:
MAKO(NACT* parent, const Config& config);
~MAKO();
void play_music(int page);
void stop_music();
bool check_music();
void get_mark(int* mark, int* loop);
void play_pcm(int page, bool loop);
void stop_pcm();
bool check_pcm();
void set_cd_track(int num, int track) { cd_track[num] = track; }
#ifdef _WIN32
void select_sound(BGMDevice dev);
void on_mci_notify(const SDL_SysWMmsg* msg);
#endif
#if defined(__ANDROID__)
void select_synthesizer(bool use_fm);
#endif
bool use_fm;
// AMUS.DAT, AMSE.DAT
char amus[16];
char amse[16];
int current_music;
int next_loop; // Y19
private:
NACT* nact;
int cd_track[100]; // Z
#if !defined(__EMSCRIPTEN__) && !defined(__ANDROID__)
bool load_playlist(const char* path);
std::vector<const char*> playlist;
#endif
};
#endif
/*
ALICE SOFT SYSTEM 3 for Win32
[ MAKO ]
*/
#ifndef _MAKO_H_
#define _MAKO_H_
#include <vector>
#include <stdio.h>
#include <limits.h>
#include <math.h>
#include "../common.h"
#include "nact.h"
enum BGMDevice {
BGM_FM,
BGM_MIDI,
BGM_CD
};
struct Config;
class MAKO
{
public:
MAKO(NACT* parent, const Config& config);
~MAKO();
void play_music(int page);
void stop_music();
bool check_music();
void get_mark(int* mark, int* loop);
void play_pcm(int page, bool loop);
void stop_pcm();
bool check_pcm();
void set_cd_track(int num, int track) { cd_track[num] = track; }
#ifdef _WIN32
void select_sound(BGMDevice dev);
void on_mci_notify(const SDL_SysWMmsg* msg);
#endif
#if defined(__ANDROID__)
void select_synthesizer(bool use_fm);
#endif
bool use_fm;
// AMUS.DAT, AMSE.DAT
char amus[16];
char amse[16];
int current_music;
int next_loop; // Y19
private:
NACT* nact;
int cd_track[100]; // Z
#if !defined(__EMSCRIPTEN__) && !defined(__ANDROID__)
bool load_playlist(const char* path);
std::vector<const char*> playlist;
#endif
};
#endif
+622 -622
View File
File diff suppressed because it is too large Load Diff
+573 -573
View File
File diff suppressed because it is too large Load Diff
+434 -434
View File
@@ -1,434 +1,434 @@
/*
ALICE SOFT SYSTEM 3 for Win32
[ NACT ]
*/
#ifndef _NACT_H_
#define _NACT_H_
#include <memory>
#include <string>
#include <stdio.h>
#include "../common.h"
#include "config.h"
#define RND var[ 0]
#define D01 var[ 1]
#define D02 var[ 2]
#define D03 var[ 3]
#define D04 var[ 4]
#define D05 var[ 5]
#define D06 var[ 6]
#define D07 var[ 7]
#define D08 var[ 8]
#define D09 var[ 9]
#define D10 var[10]
#define D11 var[11]
#define D12 var[12]
#define D13 var[13]
#define D14 var[14]
#define D15 var[15]
#define D16 var[16]
#define D17 var[17]
#define D18 var[18]
#define D19 var[19]
#define D20 var[20]
#define U01 var[21]
#define U02 var[22]
#define U03 var[23]
#define U04 var[24]
#define U05 var[25]
#define U06 var[26]
#define U07 var[27]
#define U08 var[28]
#define U09 var[29]
#define U10 var[30]
#define U11 var[31]
#define U12 var[32]
#define U13 var[33]
#define U14 var[34]
#define U15 var[35]
#define U16 var[36]
#define U17 var[37]
#define U18 var[38]
#define U19 var[39]
#define U20 var[40]
#define B01 var[41]
#define B02 var[42]
#define B03 var[43]
#define B04 var[44]
#define B05 var[45]
#define B06 var[46]
#define B07 var[47]
#define B08 var[48]
#define B09 var[49]
#define B10 var[50]
#define B11 var[51]
#define B12 var[52]
#define B13 var[53]
#define B14 var[54]
#define B15 var[55]
#define B16 var[56]
#define M_X var[57]
#define M_Y var[58]
#define MAX_STACK 100
#define MAX_MENU 64
#define MAX_VERB 128
#define MAX_OBJ 256
#define MAX_CAPTION 32
#define MAX_PCM 256
class AGS;
class MAKO;
class MsgSkip;
class Encoding;
enum Language {
JAPANESE = 0,
ENGLISH = 1,
};
class NACT
{
public:
static NACT* create(const Config& config);
NACT(int sys_ver, uint32 crc32_a, uint32 crc32_b, const Config& config);
virtual ~NACT();
protected:
AGS* ags;
MAKO* mako;
MsgSkip* msgskip;
// コマンドパーサ
void execute();
void load_scenario(int page);
bool fatal_error = false;
bool post_quit = false;
// ADISK.DAT, ASLEEP.DAT
char adisk[16];
// シナリオデータ
uint8* scenario_data;
int scenario_size;
// アドレス、ページ管理
int scenario_addr, prev_addr;
int scenario_page;
int label_depth;
int label_stack[MAX_STACK];
int page_depth;
int page_stack[MAX_STACK];
int addr_stack[MAX_STACK];
// 変数
uint16 var[512];
uint16 var_stack[30][20];
// char tvar[10][22];
char tvar_stack[30][10][22];
// int tvar_index;
void message(uint8 terminator);
// Commands
virtual void cmd_calc() = 0;
virtual void cmd_branch() = 0;
virtual void cmd_label_jump() = 0;
virtual void cmd_label_call() = 0;
virtual void cmd_page_jump() = 0;
virtual void cmd_page_call() = 0;
virtual void cmd_set_menu() = 0;
virtual void cmd_open_menu() = 0;
virtual void cmd_set_verbobj() = 0;
virtual void cmd_set_verbobj2() = 0;
virtual void cmd_open_verb() = 0;
virtual void cmd_open_obj(int verb) = 0;
virtual void cmd_a() = 0;
virtual void cmd_b() = 0;
virtual void cmd_d() = 0;
virtual void cmd_e() = 0;
virtual void cmd_f() = 0;
virtual void cmd_g() = 0;
virtual void cmd_h() = 0;
virtual void cmd_i() = 0;
virtual void cmd_j() = 0;
virtual void cmd_k() = 0;
virtual void cmd_l() = 0;
virtual void cmd_m() = 0;
virtual void cmd_n() = 0;
virtual void cmd_o() = 0;
virtual void cmd_p() = 0;
virtual void cmd_q() = 0;
virtual void cmd_r() = 0;
virtual void cmd_s() = 0;
virtual void cmd_t() = 0;
virtual void cmd_u() = 0;
virtual void cmd_v() = 0;
virtual void cmd_w() = 0;
virtual void cmd_x() = 0;
virtual void cmd_y() = 0;
virtual void cmd_z() = 0;
// SYSTEM1
virtual void opening() {}
// DPS
bool text_refresh;
bool column; // 座標モード
bool wait_keydown; // ウェイト時のキー受付
int text_wait_time; // テキスト表示のウェイト
int mouse_sence; // マウス感度
int menu_window; // メニューウィンドウ番号
int text_window; // メッセージウィンドウ番号
bool show_push; // Push表示
bool clear_text; // メニュー後のメッセージウィンドウ消去
int menu_index; // メニュー登録のインデックス
int menu_addr[64]; // ジャンプ先のアドレス
int menu_verb[64]; // 登録された動詞
int menu_obj[64]; // 登録された目的語
char caption_verb[MAX_VERB][MAX_CAPTION];
char caption_obj[MAX_OBJ][MAX_CAPTION];
bool verb_obj; // 動詞-形容詞型メニューの定義中
bool set_palette;
int pcm_index;
int pcm[MAX_PCM];
// 下位関数
virtual uint16 cali() = 0;
virtual uint16 cali2() = 0;
uint8 getd() { return scenario_data[scenario_addr++]; }
uint16 getw() {
uint16 val = scenario_data[scenario_addr] | (scenario_data[scenario_addr + 1] << 8);
scenario_addr += 2;
return val;
}
void ungetd() { scenario_addr--; }
bool is_message(uint8_t c) { return c == ' ' || c & 0x80; }
void skip_string(uint8 terminator);
void get_string(char* buf, int size, uint8 terminator);
uint16 random(uint16 range);
uint32 seed;
int menu_select(int num_items);
void wait_after_open_menu();
uint8 get_key();
void get_cursor(int* x, int* y);
void set_cursor(int x, int y);
#ifdef USE_JOY
int joy_num;
JOYCAPS joycaps;
#endif
int mouse_x = 0, mouse_y = 0;
static uint32 calc_crc32(const char* file_name, const std::string& game_id);
// Y27 ダイアログ
void text_dialog();
// 終了フラグ
bool terminate;
bool restart_after_terminate;
// Platform-specific setup / cleanup code
void platform_initialize();
void platform_finalize();
public:
bool mainloop();
void sys_sleep(int ms);
int get_screen_height();
void select_cursor();
const char* get_game_id();
static const int get_sys_ver(uint32 crc32_a, uint32 crc32_b);
const char* get_title();
Language get_language();
const char* get_encoding_name();
void text_wait();
void set_skip_menu_state(bool enabled, bool checked);
bool text_wait_enb; // テキスト表示のウェイト有効/無効
int sys_ver;
uint32 crc32_a; // ADISK
uint32 crc32_b; // BDISK for D.P.S -SG- and Super D.P.S
const Config& config;
std::unique_ptr<Encoding> encoding;
Strings strings;
// for Y27
char tvar[10][33];
int tvar_index, tvar_maxlen;
// デバッグログ
void output_console(const char *format, ...);
int get_scenario_page() const { return scenario_page; }
void fatal(const char* msg, ...);
private:
void pump_events();
bool handle_platform_event(const SDL_Event& e);
};
class NACT_Sys1 final : public NACT {
public:
NACT_Sys1(uint32 crc32_a, uint32 crc32_b, const Config& config);
protected:
void cmd_calc() override;
void cmd_branch() override;
void cmd_label_jump() override;
void cmd_label_call() override;
void cmd_page_jump() override;
void cmd_page_call() override;
void cmd_set_menu() override;
void cmd_open_menu() override;
void cmd_set_verbobj() override;
void cmd_set_verbobj2() override;
void cmd_open_verb() override;
void cmd_open_obj(int verb) override;
void cmd_a() override;
void cmd_b() override;
void cmd_d() override;
void cmd_e() override;
void cmd_f() override;
void cmd_g() override;
void cmd_h() override;
void cmd_i() override;
void cmd_j() override;
void cmd_k() override;
void cmd_l() override;
void cmd_m() override;
void cmd_n() override;
void cmd_o() override;
void cmd_p() override;
void cmd_q() override;
void cmd_r() override;
void cmd_s() override;
void cmd_t() override;
void cmd_u() override;
void cmd_v() override;
void cmd_w() override;
void cmd_x() override;
void cmd_y() override;
void cmd_z() override;
void opening() override;
uint16 cali() override;
uint16 cali2() override;
private:
// Intruder Zコマンド
int paint_x;
int paint_y;
int map_page;
};
class NACT_Sys2 final : public NACT {
public:
NACT_Sys2(uint32 crc32_a, uint32 crc32_b, const Config& config);
protected:
void cmd_calc() override;
void cmd_branch() override;
void cmd_label_jump() override;
void cmd_label_call() override;
void cmd_page_jump() override;
void cmd_page_call() override;
void cmd_set_menu() override;
void cmd_open_menu() override;
void cmd_set_verbobj() override;
void cmd_set_verbobj2() override;
void cmd_open_verb() override;
void cmd_open_obj(int verb) override;
void cmd_a() override;
void cmd_b() override;
void cmd_d() override;
void cmd_e() override;
void cmd_f() override;
void cmd_g() override;
void cmd_h() override;
void cmd_i() override;
void cmd_j() override;
void cmd_k() override;
void cmd_l() override;
void cmd_m() override;
void cmd_n() override;
void cmd_o() override;
void cmd_p() override;
void cmd_q() override;
void cmd_r() override;
void cmd_s() override;
void cmd_t() override;
void cmd_u() override;
void cmd_v() override;
void cmd_w() override;
void cmd_x() override;
void cmd_y() override;
void cmd_z() override;
uint16 cali() override;
uint16 cali2() override;
};
class NACT_Sys3 final : public NACT {
public:
NACT_Sys3(uint32 crc32_a, uint32 crc32_b, const Config& config);
protected:
void cmd_calc() override;
void cmd_branch() override;
void cmd_label_jump() override;
void cmd_label_call() override;
void cmd_page_jump() override;
void cmd_page_call() override;
void cmd_set_menu() override;
void cmd_open_menu() override;
void cmd_set_verbobj() override;
void cmd_set_verbobj2() override;
void cmd_open_verb() override;
void cmd_open_obj(int verb) override;
void cmd_a() override;
void cmd_b() override;
void cmd_d() override;
void cmd_e() override;
void cmd_f() override;
void cmd_g() override;
void cmd_h() override;
void cmd_i() override;
void cmd_j() override;
void cmd_k() override;
void cmd_l() override;
void cmd_m() override;
void cmd_n() override;
void cmd_o() override;
void cmd_p() override;
void cmd_q() override;
void cmd_r() override;
void cmd_s() override;
void cmd_t() override;
void cmd_u() override;
void cmd_v() override;
void cmd_w() override;
void cmd_x() override;
void cmd_y() override;
void cmd_z() override;
uint16 cali() override;
uint16 cali2() override;
};
#endif // _NACT_H_
/*
ALICE SOFT SYSTEM 3 for Win32
[ NACT ]
*/
#ifndef _NACT_H_
#define _NACT_H_
#include <memory>
#include <string>
#include <stdio.h>
#include "../common.h"
#include "config.h"
#define RND var[ 0]
#define D01 var[ 1]
#define D02 var[ 2]
#define D03 var[ 3]
#define D04 var[ 4]
#define D05 var[ 5]
#define D06 var[ 6]
#define D07 var[ 7]
#define D08 var[ 8]
#define D09 var[ 9]
#define D10 var[10]
#define D11 var[11]
#define D12 var[12]
#define D13 var[13]
#define D14 var[14]
#define D15 var[15]
#define D16 var[16]
#define D17 var[17]
#define D18 var[18]
#define D19 var[19]
#define D20 var[20]
#define U01 var[21]
#define U02 var[22]
#define U03 var[23]
#define U04 var[24]
#define U05 var[25]
#define U06 var[26]
#define U07 var[27]
#define U08 var[28]
#define U09 var[29]
#define U10 var[30]
#define U11 var[31]
#define U12 var[32]
#define U13 var[33]
#define U14 var[34]
#define U15 var[35]
#define U16 var[36]
#define U17 var[37]
#define U18 var[38]
#define U19 var[39]
#define U20 var[40]
#define B01 var[41]
#define B02 var[42]
#define B03 var[43]
#define B04 var[44]
#define B05 var[45]
#define B06 var[46]
#define B07 var[47]
#define B08 var[48]
#define B09 var[49]
#define B10 var[50]
#define B11 var[51]
#define B12 var[52]
#define B13 var[53]
#define B14 var[54]
#define B15 var[55]
#define B16 var[56]
#define M_X var[57]
#define M_Y var[58]
#define MAX_STACK 100
#define MAX_MENU 64
#define MAX_VERB 128
#define MAX_OBJ 256
#define MAX_CAPTION 32
#define MAX_PCM 256
class AGS;
class MAKO;
class MsgSkip;
class Encoding;
enum Language {
JAPANESE = 0,
ENGLISH = 1,
};
class NACT
{
public:
static NACT* create(const Config& config);
NACT(int sys_ver, uint32 crc32_a, uint32 crc32_b, const Config& config);
virtual ~NACT();
protected:
AGS* ags;
MAKO* mako;
MsgSkip* msgskip;
// コマンドパーサ
void execute();
void load_scenario(int page);
bool fatal_error = false;
bool post_quit = false;
// ADISK.DAT, ASLEEP.DAT
char adisk[16];
// シナリオデータ
uint8* scenario_data;
int scenario_size;
// アドレス、ページ管理
int scenario_addr, prev_addr;
int scenario_page;
int label_depth;
int label_stack[MAX_STACK];
int page_depth;
int page_stack[MAX_STACK];
int addr_stack[MAX_STACK];
// 変数
uint16 var[512];
uint16 var_stack[30][20];
// char tvar[10][22];
char tvar_stack[30][10][22];
// int tvar_index;
void message(uint8 terminator);
// Commands
virtual void cmd_calc() = 0;
virtual void cmd_branch() = 0;
virtual void cmd_label_jump() = 0;
virtual void cmd_label_call() = 0;
virtual void cmd_page_jump() = 0;
virtual void cmd_page_call() = 0;
virtual void cmd_set_menu() = 0;
virtual void cmd_open_menu() = 0;
virtual void cmd_set_verbobj() = 0;
virtual void cmd_set_verbobj2() = 0;
virtual void cmd_open_verb() = 0;
virtual void cmd_open_obj(int verb) = 0;
virtual void cmd_a() = 0;
virtual void cmd_b() = 0;
virtual void cmd_d() = 0;
virtual void cmd_e() = 0;
virtual void cmd_f() = 0;
virtual void cmd_g() = 0;
virtual void cmd_h() = 0;
virtual void cmd_i() = 0;
virtual void cmd_j() = 0;
virtual void cmd_k() = 0;
virtual void cmd_l() = 0;
virtual void cmd_m() = 0;
virtual void cmd_n() = 0;
virtual void cmd_o() = 0;
virtual void cmd_p() = 0;
virtual void cmd_q() = 0;
virtual void cmd_r() = 0;
virtual void cmd_s() = 0;
virtual void cmd_t() = 0;
virtual void cmd_u() = 0;
virtual void cmd_v() = 0;
virtual void cmd_w() = 0;
virtual void cmd_x() = 0;
virtual void cmd_y() = 0;
virtual void cmd_z() = 0;
// SYSTEM1
virtual void opening() {}
// DPS
bool text_refresh;
bool column; // 座標モード
bool wait_keydown; // ウェイト時のキー受付
int text_wait_time; // テキスト表示のウェイト
int mouse_sence; // マウス感度
int menu_window; // メニューウィンドウ番号
int text_window; // メッセージウィンドウ番号
bool show_push; // Push表示
bool clear_text; // メニュー後のメッセージウィンドウ消去
int menu_index; // メニュー登録のインデックス
int menu_addr[64]; // ジャンプ先のアドレス
int menu_verb[64]; // 登録された動詞
int menu_obj[64]; // 登録された目的語
char caption_verb[MAX_VERB][MAX_CAPTION];
char caption_obj[MAX_OBJ][MAX_CAPTION];
bool verb_obj; // 動詞-形容詞型メニューの定義中
bool set_palette;
int pcm_index;
int pcm[MAX_PCM];
// 下位関数
virtual uint16 cali() = 0;
virtual uint16 cali2() = 0;
uint8 getd() { return scenario_data[scenario_addr++]; }
uint16 getw() {
uint16 val = scenario_data[scenario_addr] | (scenario_data[scenario_addr + 1] << 8);
scenario_addr += 2;
return val;
}
void ungetd() { scenario_addr--; }
bool is_message(uint8_t c) { return c == ' ' || c & 0x80; }
void skip_string(uint8 terminator);
void get_string(char* buf, int size, uint8 terminator);
uint16 random(uint16 range);
uint32 seed;
int menu_select(int num_items);
void wait_after_open_menu();
uint8 get_key();
void get_cursor(int* x, int* y);
void set_cursor(int x, int y);
#ifdef USE_JOY
int joy_num;
JOYCAPS joycaps;
#endif
int mouse_x = 0, mouse_y = 0;
static uint32 calc_crc32(const char* file_name, const std::string& game_id);
// Y27 ダイアログ
void text_dialog();
// 終了フラグ
bool terminate;
bool restart_after_terminate;
// Platform-specific setup / cleanup code
void platform_initialize();
void platform_finalize();
public:
bool mainloop();
void sys_sleep(int ms);
int get_screen_height();
void select_cursor();
const char* get_game_id();
static const int get_sys_ver(uint32 crc32_a, uint32 crc32_b);
const char* get_title();
Language get_language();
const char* get_encoding_name();
void text_wait();
void set_skip_menu_state(bool enabled, bool checked);
bool text_wait_enb; // テキスト表示のウェイト有効/無効
int sys_ver;
uint32 crc32_a; // ADISK
uint32 crc32_b; // BDISK for D.P.S -SG- and Super D.P.S
const Config& config;
std::unique_ptr<Encoding> encoding;
Strings strings;
// for Y27
char tvar[10][33];
int tvar_index, tvar_maxlen;
// デバッグログ
void output_console(const char *format, ...);
int get_scenario_page() const { return scenario_page; }
void fatal(const char* msg, ...);
private:
void pump_events();
bool handle_platform_event(const SDL_Event& e);
};
class NACT_Sys1 final : public NACT {
public:
NACT_Sys1(uint32 crc32_a, uint32 crc32_b, const Config& config);
protected:
void cmd_calc() override;
void cmd_branch() override;
void cmd_label_jump() override;
void cmd_label_call() override;
void cmd_page_jump() override;
void cmd_page_call() override;
void cmd_set_menu() override;
void cmd_open_menu() override;
void cmd_set_verbobj() override;
void cmd_set_verbobj2() override;
void cmd_open_verb() override;
void cmd_open_obj(int verb) override;
void cmd_a() override;
void cmd_b() override;
void cmd_d() override;
void cmd_e() override;
void cmd_f() override;
void cmd_g() override;
void cmd_h() override;
void cmd_i() override;
void cmd_j() override;
void cmd_k() override;
void cmd_l() override;
void cmd_m() override;
void cmd_n() override;
void cmd_o() override;
void cmd_p() override;
void cmd_q() override;
void cmd_r() override;
void cmd_s() override;
void cmd_t() override;
void cmd_u() override;
void cmd_v() override;
void cmd_w() override;
void cmd_x() override;
void cmd_y() override;
void cmd_z() override;
void opening() override;
uint16 cali() override;
uint16 cali2() override;
private:
// Intruder Zコマンド
int paint_x;
int paint_y;
int map_page;
};
class NACT_Sys2 final : public NACT {
public:
NACT_Sys2(uint32 crc32_a, uint32 crc32_b, const Config& config);
protected:
void cmd_calc() override;
void cmd_branch() override;
void cmd_label_jump() override;
void cmd_label_call() override;
void cmd_page_jump() override;
void cmd_page_call() override;
void cmd_set_menu() override;
void cmd_open_menu() override;
void cmd_set_verbobj() override;
void cmd_set_verbobj2() override;
void cmd_open_verb() override;
void cmd_open_obj(int verb) override;
void cmd_a() override;
void cmd_b() override;
void cmd_d() override;
void cmd_e() override;
void cmd_f() override;
void cmd_g() override;
void cmd_h() override;
void cmd_i() override;
void cmd_j() override;
void cmd_k() override;
void cmd_l() override;
void cmd_m() override;
void cmd_n() override;
void cmd_o() override;
void cmd_p() override;
void cmd_q() override;
void cmd_r() override;
void cmd_s() override;
void cmd_t() override;
void cmd_u() override;
void cmd_v() override;
void cmd_w() override;
void cmd_x() override;
void cmd_y() override;
void cmd_z() override;
uint16 cali() override;
uint16 cali2() override;
};
class NACT_Sys3 final : public NACT {
public:
NACT_Sys3(uint32 crc32_a, uint32 crc32_b, const Config& config);
protected:
void cmd_calc() override;
void cmd_branch() override;
void cmd_label_jump() override;
void cmd_label_call() override;
void cmd_page_jump() override;
void cmd_page_call() override;
void cmd_set_menu() override;
void cmd_open_menu() override;
void cmd_set_verbobj() override;
void cmd_set_verbobj2() override;
void cmd_open_verb() override;
void cmd_open_obj(int verb) override;
void cmd_a() override;
void cmd_b() override;
void cmd_d() override;
void cmd_e() override;
void cmd_f() override;
void cmd_g() override;
void cmd_h() override;
void cmd_i() override;
void cmd_j() override;
void cmd_k() override;
void cmd_l() override;
void cmd_m() override;
void cmd_n() override;
void cmd_o() override;
void cmd_p() override;
void cmd_q() override;
void cmd_r() override;
void cmd_s() override;
void cmd_t() override;
void cmd_u() override;
void cmd_v() override;
void cmd_w() override;
void cmd_x() override;
void cmd_y() override;
void cmd_z() override;
uint16 cali() override;
uint16 cali2() override;
};
#endif // _NACT_H_
+170 -170
View File
@@ -1,170 +1,170 @@
/*
ALICE SOFT SYSTEM 3 for Win32
[ NACT - crc32 ]
*/
#include "nact.h"
#include <string.h>
#include "crc32.h"
#include "../fileio.h"
#include "config.h"
namespace {
const struct CRCTable {
const char* id;
int sys_ver;
const char* title;
Language language;
uint32 crc32_a;
uint32 crc32_b;
} crc_table[] = {
{"bunkasai", 1, "あぶない文化祭前夜", JAPANESE, CRC32_BUNKASAI},
{"crescent", 1, "クレセントムーンがぁる", JAPANESE, CRC32_CRESCENT},
{"dps", 1, "D.P.S - Dream Program System", JAPANESE, CRC32_DPS},
{"dps_sg_fahren", 1, "D.P.S SG - Fahren Fliegen", JAPANESE, CRC32_DPS_SG, CRC32_DPS_SG_FAHREN},
{"dps_sg_katei", 1, "D.P.S SG - 家庭教師はステキなお仕事", JAPANESE, CRC32_DPS_SG, CRC32_DPS_SG_KATEI},
{"dps_sg_nobunaga", 1, "D.P.S SG - 信長の淫謀", JAPANESE, CRC32_DPS_SG, CRC32_DPS_SG_NOBUNAGA},
{"dps_sg2_antique", 1, "D.P.S SG set2 - ANTIQUE HOUSE", JAPANESE, CRC32_DPS_SG2, CRC32_DPS_SG2_ANTIQUE},
{"dps_sg2_ikenai", 1, "D.P.S SG set2 - いけない内科検診再び", JAPANESE, CRC32_DPS_SG2, CRC32_DPS_SG2_IKENAI},
{"dps_sg2_akai", 1, "D.P.S SG set2 - 朱い夜", JAPANESE, CRC32_DPS_SG2, CRC32_DPS_SG2_AKAI},
{"dps_sg3_rabbit", 1, "D.P.S SG set3 - Rabbit P4P", JAPANESE, CRC32_DPS_SG3, CRC32_DPS_SG3_RABBIT},
{"dps_sg3_shinkon", 1, "D.P.S SG set3 - しんこんさんものがたり", JAPANESE, CRC32_DPS_SG3, CRC32_DPS_SG3_SHINKON},
{"dps_sg3_sotsugyou", 1, "D.P.S SG set3 - 卒業", JAPANESE, CRC32_DPS_SG3, CRC32_DPS_SG3_SOTSUGYOU},
{"fukei", 1, "婦警さんVX", JAPANESE, CRC32_FUKEI},
{"intruder", 1, "Intruder -桜屋敷の探索-", JAPANESE, CRC32_INTRUDER},
{"tengu", 1, "あぶないてんぐ伝説", JAPANESE, CRC32_TENGU},
{"toushin_hint", 1, "闘神都市 ヒントディスク", JAPANESE, CRC32_TOUSHIN_HINT},
{"little_vampire", 1, "Little Vampire", JAPANESE, CRC32_VAMPIRE},
{"little_vampire_eng", 1, "Little Vampire", ENGLISH, CRC32_VAMPIRE_ENG},
{"yakata", 1, "ALICEの館", JAPANESE, CRC32_YAKATA},
{"ayumi_fd", 2, "あゆみちゃん物語", JAPANESE, CRC32_AYUMI_FD},
{"ayumi_hint", 2, "あゆみちゃん物語 ヒントディスク", JAPANESE, CRC32_AYUMI_HINT},
{"ayumi_proto", 2, "あゆみちゃん物語 PROTO", JAPANESE, CRC32_AYUMI_PROTO},
{"dalk_hint", 2, "DALK ヒントディスク", JAPANESE, CRC32_DALK_HINT},
{"drstop", 2, "Dr. STOP!", JAPANESE, CRC32_DRSTOP},
{"prog_fd", 2, "Prostudent G", JAPANESE, CRC32_PROSTUDENTG_FD},
{"rance3_hint", 2, "Rance3 ヒントディスク", JAPANESE, CRC32_RANCE3_HINT},
{"sdps_maria", 2, "Super D.P.S - マリアとカンパン", JAPANESE, CRC32_SDPS, CRC32_SDPS_MARIA},
{"sdps_tono", 2, "Super D.P.S - 遠野の森", JAPANESE, CRC32_SDPS, CRC32_SDPS_TONO},
{"sdps_kaizoku", 2, "Super D.P.S - うれしたのし海賊稼業", JAPANESE, CRC32_SDPS, CRC32_SDPS_KAIZOKU},
{"yakata2", 2, "ALICEの館II", JAPANESE, CRC32_YAKATA2},
{"ambivalenz_fd", 3, "AmbivalenZ −二律背反−", JAPANESE, CRC32_AMBIVALENZ_FD},
{"ambivalenz_cd", 3, "AmbivalenZ −二律背反−", JAPANESE, CRC32_AMBIVALENZ_CD},
{"dps_all", 3, "D.P.S. 全部", JAPANESE, CRC32_DPSALL},
{"funnybee_cd", 3, "宇宙快盗ファニーBee", JAPANESE, CRC32_FUNNYBEE_CD},
// {"funnybee_patch", 3, "宇宙快盗ファニーBee", JAPANESE, CRC32_FUNNYBEE_PATCH},
{"funnybee_fd", 3, "宇宙快盗ファニーBee", JAPANESE, CRC32_FUNNYBEE_FD},
{"onlyyou", 3, "Only You −世紀末のジュリエット達−", JAPANESE, CRC32_ONLYYOU},
{"onlyyou_demo", 3, "Only You −世紀末のジュリエット達− デモ版", JAPANESE, CRC32_ONLYYOU_DEMO},
{"prog_cd", 3, "Prostudent G", JAPANESE, CRC32_PROSTUDENTG_CD},
{"prog_omake", 3, "Prostudent G おまけ", JAPANESE, CRC32_PROG_OMAKE},
{"rance41", 3, "ランス 4.1 〜お薬工場を救え!〜", JAPANESE, CRC32_RANCE41},
{"rance41_eng", 3, "Rance 4.1 ~Save the Medicine Plant!~", ENGLISH, CRC32_RANCE41_ENG},
{"rance42", 3, "ランス 4.2 〜エンジェル組〜", JAPANESE, CRC32_RANCE42},
{"rance42_eng", 3, "Rance 4.2 ~Angel Army~", ENGLISH, CRC32_RANCE42_ENG},
{"ayumi_cd", 3, "あゆみちゃん物語", JAPANESE, CRC32_AYUMI_CD},
{"ayumi_live_256", 3, "あゆみちゃん物語 実写版", JAPANESE, CRC32_AYUMI_JISSHA_256},
{"ayumi_live_full", 3, "あゆみちゃん物語 フルカラー実写版", JAPANESE, CRC32_AYUMI_JISSHA_FULL},
{"yakata3_cd", 3, "アリスの館3", JAPANESE, CRC32_YAKATA3_CD},
{"yakata3_fd", 3, "アリスの館3", JAPANESE, CRC32_YAKATA3_FD},
{"hashirionna2", 3, "走り女2", JAPANESE, CRC32_HASHIRIONNA2},
{"toushin2_gd", 3,"闘神都市2 グラフィックディスク", JAPANESE, CRC32_TOUSHIN2_GD},
{"toushin2_sp", 3, "闘神都市2 そして、それから…", JAPANESE, CRC32_TOUSHIN2_SP},
{"otome", 3, "乙女戦記", JAPANESE, CRC32_OTOMESENKI},
{"ningyo", 3, "人魚 -蘿子-", JAPANESE, CRC32_NINGYO},
{"mugen", 3, "夢幻泡影", JAPANESE, CRC32_MUGENHOUYOU},
{NULL},
};
const CRCTable* lookup(uint32 crc32_a, uint32 crc32_b)
{
for (const CRCTable* t = crc_table; t->id; t++) {
if (crc32_a == t->crc32_a && (!t->crc32_b || crc32_b == t->crc32_b))
return t;
}
return NULL;
}
} // namespace
uint32 NACT::calc_crc32(const char* file_name, const std::string& game_id)
{
if (!game_id.empty()) {
for (const CRCTable* t = crc_table; t->id; t++) {
if (t->id == game_id)
return file_name[0] == 'A' ? t->crc32_a : t->crc32_b;
}
}
uint32 crc = 0;
FILEIO* fio = new FILEIO();
if(fio->Fopen(file_name, FILEIO_READ_BINARY)) {
uint32 table[256];
for(int i = 0; i < 256; i++) {
uint32 c = i;
for(int j = 0; j < 8; j++) {
if(c & 1) {
c = (c >> 1) ^ 0xedb88320;
} else {
c >>= 1;
}
}
table[i] = c;
}
// ADISK.DATの先頭256bytes
for(int i = 0; i < 256; i++) {
int d = fio->Fgetc();
uint32 c = ~crc;
c = table[(c ^ d) & 0xff] ^ (c >> 8);
crc = ~c;
}
fio->Fclose();
}
delete fio;
return crc;
}
const char* NACT::get_game_id()
{
if (const CRCTable* entry = lookup(crc32_a, crc32_b))
return entry->id;
return NULL;
}
const int NACT::get_sys_ver(uint32 crc32_a, uint32 crc32_b)
{
if (const CRCTable* entry = lookup(crc32_a, crc32_b))
return entry->sys_ver;
return 3;
}
const char* NACT::get_title()
{
if (!config.title.empty())
return config.title.c_str();
if (const CRCTable* entry = lookup(crc32_a, crc32_b))
return entry->title;
return NULL;
}
Language NACT::get_language()
{
if (const CRCTable* entry = lookup(crc32_a, crc32_b))
return entry->language;
return JAPANESE;
}
const char* NACT::get_encoding_name()
{
if (!config.encoding.empty())
return config.encoding.c_str();
// TODO: Determine encoding from crc32
return "Shift_JIS";
}
/*
ALICE SOFT SYSTEM 3 for Win32
[ NACT - crc32 ]
*/
#include "nact.h"
#include <string.h>
#include "crc32.h"
#include "../fileio.h"
#include "config.h"
namespace {
const struct CRCTable {
const char* id;
int sys_ver;
const char* title;
Language language;
uint32 crc32_a;
uint32 crc32_b;
} crc_table[] = {
{"bunkasai", 1, "あぶない文化祭前夜", JAPANESE, CRC32_BUNKASAI},
{"crescent", 1, "クレセントムーンがぁる", JAPANESE, CRC32_CRESCENT},
{"dps", 1, "D.P.S - Dream Program System", JAPANESE, CRC32_DPS},
{"dps_sg_fahren", 1, "D.P.S SG - Fahren Fliegen", JAPANESE, CRC32_DPS_SG, CRC32_DPS_SG_FAHREN},
{"dps_sg_katei", 1, "D.P.S SG - 家庭教師はステキなお仕事", JAPANESE, CRC32_DPS_SG, CRC32_DPS_SG_KATEI},
{"dps_sg_nobunaga", 1, "D.P.S SG - 信長の淫謀", JAPANESE, CRC32_DPS_SG, CRC32_DPS_SG_NOBUNAGA},
{"dps_sg2_antique", 1, "D.P.S SG set2 - ANTIQUE HOUSE", JAPANESE, CRC32_DPS_SG2, CRC32_DPS_SG2_ANTIQUE},
{"dps_sg2_ikenai", 1, "D.P.S SG set2 - いけない内科検診再び", JAPANESE, CRC32_DPS_SG2, CRC32_DPS_SG2_IKENAI},
{"dps_sg2_akai", 1, "D.P.S SG set2 - 朱い夜", JAPANESE, CRC32_DPS_SG2, CRC32_DPS_SG2_AKAI},
{"dps_sg3_rabbit", 1, "D.P.S SG set3 - Rabbit P4P", JAPANESE, CRC32_DPS_SG3, CRC32_DPS_SG3_RABBIT},
{"dps_sg3_shinkon", 1, "D.P.S SG set3 - しんこんさんものがたり", JAPANESE, CRC32_DPS_SG3, CRC32_DPS_SG3_SHINKON},
{"dps_sg3_sotsugyou", 1, "D.P.S SG set3 - 卒業", JAPANESE, CRC32_DPS_SG3, CRC32_DPS_SG3_SOTSUGYOU},
{"fukei", 1, "婦警さんVX", JAPANESE, CRC32_FUKEI},
{"intruder", 1, "Intruder -桜屋敷の探索-", JAPANESE, CRC32_INTRUDER},
{"tengu", 1, "あぶないてんぐ伝説", JAPANESE, CRC32_TENGU},
{"toushin_hint", 1, "闘神都市 ヒントディスク", JAPANESE, CRC32_TOUSHIN_HINT},
{"little_vampire", 1, "Little Vampire", JAPANESE, CRC32_VAMPIRE},
{"little_vampire_eng", 1, "Little Vampire", ENGLISH, CRC32_VAMPIRE_ENG},
{"yakata", 1, "ALICEの館", JAPANESE, CRC32_YAKATA},
{"ayumi_fd", 2, "あゆみちゃん物語", JAPANESE, CRC32_AYUMI_FD},
{"ayumi_hint", 2, "あゆみちゃん物語 ヒントディスク", JAPANESE, CRC32_AYUMI_HINT},
{"ayumi_proto", 2, "あゆみちゃん物語 PROTO", JAPANESE, CRC32_AYUMI_PROTO},
{"dalk_hint", 2, "DALK ヒントディスク", JAPANESE, CRC32_DALK_HINT},
{"drstop", 2, "Dr. STOP!", JAPANESE, CRC32_DRSTOP},
{"prog_fd", 2, "Prostudent G", JAPANESE, CRC32_PROSTUDENTG_FD},
{"rance3_hint", 2, "Rance3 ヒントディスク", JAPANESE, CRC32_RANCE3_HINT},
{"sdps_maria", 2, "Super D.P.S - マリアとカンパン", JAPANESE, CRC32_SDPS, CRC32_SDPS_MARIA},
{"sdps_tono", 2, "Super D.P.S - 遠野の森", JAPANESE, CRC32_SDPS, CRC32_SDPS_TONO},
{"sdps_kaizoku", 2, "Super D.P.S - うれしたのし海賊稼業", JAPANESE, CRC32_SDPS, CRC32_SDPS_KAIZOKU},
{"yakata2", 2, "ALICEの館II", JAPANESE, CRC32_YAKATA2},
{"ambivalenz_fd", 3, "AmbivalenZ −二律背反−", JAPANESE, CRC32_AMBIVALENZ_FD},
{"ambivalenz_cd", 3, "AmbivalenZ −二律背反−", JAPANESE, CRC32_AMBIVALENZ_CD},
{"dps_all", 3, "D.P.S. 全部", JAPANESE, CRC32_DPSALL},
{"funnybee_cd", 3, "宇宙快盗ファニーBee", JAPANESE, CRC32_FUNNYBEE_CD},
// {"funnybee_patch", 3, "宇宙快盗ファニーBee", JAPANESE, CRC32_FUNNYBEE_PATCH},
{"funnybee_fd", 3, "宇宙快盗ファニーBee", JAPANESE, CRC32_FUNNYBEE_FD},
{"onlyyou", 3, "Only You −世紀末のジュリエット達−", JAPANESE, CRC32_ONLYYOU},
{"onlyyou_demo", 3, "Only You −世紀末のジュリエット達− デモ版", JAPANESE, CRC32_ONLYYOU_DEMO},
{"prog_cd", 3, "Prostudent G", JAPANESE, CRC32_PROSTUDENTG_CD},
{"prog_omake", 3, "Prostudent G おまけ", JAPANESE, CRC32_PROG_OMAKE},
{"rance41", 3, "ランス 4.1 〜お薬工場を救え!〜", JAPANESE, CRC32_RANCE41},
{"rance41_eng", 3, "Rance 4.1 ~Save the Medicine Plant!~", ENGLISH, CRC32_RANCE41_ENG},
{"rance42", 3, "ランス 4.2 〜エンジェル組〜", JAPANESE, CRC32_RANCE42},
{"rance42_eng", 3, "Rance 4.2 ~Angel Army~", ENGLISH, CRC32_RANCE42_ENG},
{"ayumi_cd", 3, "あゆみちゃん物語", JAPANESE, CRC32_AYUMI_CD},
{"ayumi_live_256", 3, "あゆみちゃん物語 実写版", JAPANESE, CRC32_AYUMI_JISSHA_256},
{"ayumi_live_full", 3, "あゆみちゃん物語 フルカラー実写版", JAPANESE, CRC32_AYUMI_JISSHA_FULL},
{"yakata3_cd", 3, "アリスの館3", JAPANESE, CRC32_YAKATA3_CD},
{"yakata3_fd", 3, "アリスの館3", JAPANESE, CRC32_YAKATA3_FD},
{"hashirionna2", 3, "走り女2", JAPANESE, CRC32_HASHIRIONNA2},
{"toushin2_gd", 3,"闘神都市2 グラフィックディスク", JAPANESE, CRC32_TOUSHIN2_GD},
{"toushin2_sp", 3, "闘神都市2 そして、それから…", JAPANESE, CRC32_TOUSHIN2_SP},
{"otome", 3, "乙女戦記", JAPANESE, CRC32_OTOMESENKI},
{"ningyo", 3, "人魚 -蘿子-", JAPANESE, CRC32_NINGYO},
{"mugen", 3, "夢幻泡影", JAPANESE, CRC32_MUGENHOUYOU},
{NULL},
};
const CRCTable* lookup(uint32 crc32_a, uint32 crc32_b)
{
for (const CRCTable* t = crc_table; t->id; t++) {
if (crc32_a == t->crc32_a && (!t->crc32_b || crc32_b == t->crc32_b))
return t;
}
return NULL;
}
} // namespace
uint32 NACT::calc_crc32(const char* file_name, const std::string& game_id)
{
if (!game_id.empty()) {
for (const CRCTable* t = crc_table; t->id; t++) {
if (t->id == game_id)
return file_name[0] == 'A' ? t->crc32_a : t->crc32_b;
}
}
uint32 crc = 0;
FILEIO* fio = new FILEIO();
if(fio->Fopen(file_name, FILEIO_READ_BINARY)) {
uint32 table[256];
for(int i = 0; i < 256; i++) {
uint32 c = i;
for(int j = 0; j < 8; j++) {
if(c & 1) {
c = (c >> 1) ^ 0xedb88320;
} else {
c >>= 1;
}
}
table[i] = c;
}
// ADISK.DATの先頭256bytes
for(int i = 0; i < 256; i++) {
int d = fio->Fgetc();
uint32 c = ~crc;
c = table[(c ^ d) & 0xff] ^ (c >> 8);
crc = ~c;
}
fio->Fclose();
}
delete fio;
return crc;
}
const char* NACT::get_game_id()
{
if (const CRCTable* entry = lookup(crc32_a, crc32_b))
return entry->id;
return NULL;
}
const int NACT::get_sys_ver(uint32 crc32_a, uint32 crc32_b)
{
if (const CRCTable* entry = lookup(crc32_a, crc32_b))
return entry->sys_ver;
return 3;
}
const char* NACT::get_title()
{
if (!config.title.empty())
return config.title.c_str();
if (const CRCTable* entry = lookup(crc32_a, crc32_b))
return entry->title;
return NULL;
}
Language NACT::get_language()
{
if (const CRCTable* entry = lookup(crc32_a, crc32_b))
return entry->language;
return JAPANESE;
}
const char* NACT::get_encoding_name()
{
if (!config.encoding.empty())
return config.encoding.c_str();
// TODO: Determine encoding from crc32
return "Shift_JIS";
}
+119 -119
View File
@@ -1,119 +1,119 @@
/*
ALICE SOFT SYSTEM 3 for Win32
[ NACT - input ]
*/
#ifdef _WIN32
#include <windows.h>
#undef ERROR
#endif
#include <SDL_syswm.h>
#include "nact.h"
#include "ags.h"
#include "texthook.h"
extern SDL_Window* g_window;
static int mousex, mousey, fingers;
void NACT::pump_events()
{
SDL_Event e;
while (SDL_PollEvent(&e)) {
if (handle_platform_event(e))
continue;
switch (e.type) {
case SDL_QUIT:
terminate = true;
break;
case SDL_WINDOWEVENT:
switch (e.window.event) {
case SDL_WINDOWEVENT_EXPOSED:
case SDL_WINDOWEVENT_SIZE_CHANGED:
ags->flush_screen(false);
break;
}
break;
case SDL_MOUSEMOTION:
mousex = e.motion.x;
mousey = e.motion.y;
break;
case SDL_FINGERDOWN:
case SDL_FINGERUP:
case SDL_FINGERMOTION:
mousex = e.tfinger.x * 640;
mousey = e.tfinger.y * ags->screen_height;
fingers = SDL_GetNumTouchFingers(e.tfinger.touchId);
break;
case SDL_APP_DIDENTERFOREGROUND:
ags->flush_screen(false);
break;
}
}
}
uint8 NACT::get_key()
{
uint8 val = 0;
texthook_keywait();
pump_events();
// キーボード&マウス
const Uint8* key = SDL_GetKeyboardState(NULL);
Uint32 mouse;
if (fingers) {
mouse = fingers == 1 ? SDL_BUTTON_LMASK : SDL_BUTTON_RMASK;
} else {
mouse = SDL_GetMouseState(NULL, NULL);
}
if(key[SDL_SCANCODE_UP ] || key[SDL_SCANCODE_KP_8 ] ) val |= 0x01;
if(key[SDL_SCANCODE_DOWN ] || key[SDL_SCANCODE_KP_2 ] ) val |= 0x02;
if(key[SDL_SCANCODE_LEFT ] || key[SDL_SCANCODE_KP_4 ] ) val |= 0x04;
if(key[SDL_SCANCODE_RIGHT ] || key[SDL_SCANCODE_KP_6 ] ) val |= 0x08;
if(key[SDL_SCANCODE_RETURN] || mouse & SDL_BUTTON_LMASK) val |= 0x10;
if(key[SDL_SCANCODE_SPACE ] || mouse & SDL_BUTTON_RMASK) val |= 0x20;
if(key[SDL_SCANCODE_ESCAPE] ) val |= 0x40;
if(key[SDL_SCANCODE_TAB ] ) val |= 0x80;
// マウス移動で方向入力はサポートしない
#ifdef USE_JOY
// ジョイスティック
if(joy_num > 0) {
JOYINFO joyinfo;
if(joyGetPos(JOYSTICKID1, &joyinfo) == JOYERR_NOERROR) {
if(joyinfo.wYpos == joycaps.wYmin) val |= 0x01;
if(joyinfo.wYpos == joycaps.wYmax) val |= 0x02;
if(joyinfo.wXpos == joycaps.wXmin) val |= 0x04;
if(joyinfo.wXpos == joycaps.wXmax) val |= 0x08;
if(joyinfo.wButtons & JOY_BUTTON1) val |= 0x10;
if(joyinfo.wButtons & JOY_BUTTON2) val |= 0x20;
if(joyinfo.wButtons & JOY_BUTTON3) val |= 0x40;
if(joyinfo.wButtons & JOY_BUTTON4) val |= 0x80;
}
}
#endif
return val;
}
void NACT::get_cursor(int* x, int* y)
{
pump_events();
*x = mousex;
*y = mousey;
}
void NACT::set_cursor(int x, int y)
{
ags->translate_mouse_coords(&x, &y);
SDL_WarpMouseInWindow(g_window, x, y);
}
/*
ALICE SOFT SYSTEM 3 for Win32
[ NACT - input ]
*/
#ifdef _WIN32
#include <windows.h>
#undef ERROR
#endif
#include <SDL_syswm.h>
#include "nact.h"
#include "ags.h"
#include "texthook.h"
extern SDL_Window* g_window;
static int mousex, mousey, fingers;
void NACT::pump_events()
{
SDL_Event e;
while (SDL_PollEvent(&e)) {
if (handle_platform_event(e))
continue;
switch (e.type) {
case SDL_QUIT:
terminate = true;
break;
case SDL_WINDOWEVENT:
switch (e.window.event) {
case SDL_WINDOWEVENT_EXPOSED:
case SDL_WINDOWEVENT_SIZE_CHANGED:
ags->flush_screen(false);
break;
}
break;
case SDL_MOUSEMOTION:
mousex = e.motion.x;
mousey = e.motion.y;
break;
case SDL_FINGERDOWN:
case SDL_FINGERUP:
case SDL_FINGERMOTION:
mousex = e.tfinger.x * 640;
mousey = e.tfinger.y * ags->screen_height;
fingers = SDL_GetNumTouchFingers(e.tfinger.touchId);
break;
case SDL_APP_DIDENTERFOREGROUND:
ags->flush_screen(false);
break;
}
}
}
uint8 NACT::get_key()
{
uint8 val = 0;
texthook_keywait();
pump_events();
// キーボード&マウス
const Uint8* key = SDL_GetKeyboardState(NULL);
Uint32 mouse;
if (fingers) {
mouse = fingers == 1 ? SDL_BUTTON_LMASK : SDL_BUTTON_RMASK;
} else {
mouse = SDL_GetMouseState(NULL, NULL);
}
if(key[SDL_SCANCODE_UP ] || key[SDL_SCANCODE_KP_8 ] ) val |= 0x01;
if(key[SDL_SCANCODE_DOWN ] || key[SDL_SCANCODE_KP_2 ] ) val |= 0x02;
if(key[SDL_SCANCODE_LEFT ] || key[SDL_SCANCODE_KP_4 ] ) val |= 0x04;
if(key[SDL_SCANCODE_RIGHT ] || key[SDL_SCANCODE_KP_6 ] ) val |= 0x08;
if(key[SDL_SCANCODE_RETURN] || mouse & SDL_BUTTON_LMASK) val |= 0x10;
if(key[SDL_SCANCODE_SPACE ] || mouse & SDL_BUTTON_RMASK) val |= 0x20;
if(key[SDL_SCANCODE_ESCAPE] ) val |= 0x40;
if(key[SDL_SCANCODE_TAB ] ) val |= 0x80;
// マウス移動で方向入力はサポートしない
#ifdef USE_JOY
// ジョイスティック
if(joy_num > 0) {
JOYINFO joyinfo;
if(joyGetPos(JOYSTICKID1, &joyinfo) == JOYERR_NOERROR) {
if(joyinfo.wYpos == joycaps.wYmin) val |= 0x01;
if(joyinfo.wYpos == joycaps.wYmax) val |= 0x02;
if(joyinfo.wXpos == joycaps.wXmin) val |= 0x04;
if(joyinfo.wXpos == joycaps.wXmax) val |= 0x08;
if(joyinfo.wButtons & JOY_BUTTON1) val |= 0x10;
if(joyinfo.wButtons & JOY_BUTTON2) val |= 0x20;
if(joyinfo.wButtons & JOY_BUTTON3) val |= 0x40;
if(joyinfo.wButtons & JOY_BUTTON4) val |= 0x80;
}
}
#endif
return val;
}
void NACT::get_cursor(int* x, int* y)
{
pump_events();
*x = mousex;
*y = mousey;
}
void NACT::set_cursor(int x, int y)
{
ags->translate_mouse_coords(&x, &y);
SDL_WarpMouseInWindow(g_window, x, y);
}
+1277 -1277
View File
File diff suppressed because it is too large Load Diff
+1367 -1367
View File
File diff suppressed because it is too large Load Diff
+1509 -1509
View File
File diff suppressed because it is too large Load Diff
+498 -498
View File
@@ -1,498 +1,498 @@
/*
ALICE SOFT SYSTEM 3 for Win32
[ MAKO ]
*/
#include <windows.h>
#undef ERROR
#include <memory>
#include <string>
#include <SDL.h>
#include <SDL_syswm.h>
#include "mako.h"
#include "mako_midi.h"
#include "fm/mako_fmgen.h"
#include "../config.h"
#include "dri.h"
#include "crc32.h"
extern SDL_Window* g_window;
namespace {
const int SAMPLE_RATE = 44100;
// Per-game mapping from music numbers to CD tracks. This is necessary to
// forcibly change the sound device with a menu command.
//
// When the game uses "Z 100+x,y" command, the xth element of the array should
// be y. The array must be terminated with -1.
const int8 RANCE41_tracks[] = {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,1,-1};
const int8 RANCE42_tracks[] = {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,1,-1};
const int8 DPSALL_tracks[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,5,1,2,3,-1};
enum MakoThreadMessage {
MAKO_OPEN = WM_APP,
MAKO_PLAY,
MAKO_STOP,
MAKO_EXIT
};
enum MakoOpenFlags {
OPEN_CD = 0,
OPEN_MIDI = 1,
};
const char* mci_geterror(DWORD err)
{
static char buf[128];
mciGetErrorString(err, buf, sizeof(buf));
return buf;
}
class MCIThread {
public:
MCIThread(NACT* nact, HWND hwnd_notify) : hwnd_notify(hwnd_notify) {
if (!_beginthreadex(NULL, 0, &MCIThread::run, this, 0, &thread_id))
nact->fatal("Cannot create thread: %s", strerror(errno));
}
bool post_message(UINT msg, WPARAM wparam, LPARAM lparam) {
return PostThreadMessage(thread_id, msg, wparam, lparam);
}
MCIDEVICEID device_id() { return devid; }
private:
static unsigned __stdcall run(void* param)
{
MCIThread* t = reinterpret_cast<MCIThread*>(param);
t->message_loop();
delete t;
return 0;
}
void message_loop()
{
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
switch (msg.message) {
case MAKO_OPEN:
close();
open(reinterpret_cast<std::string*>(msg.wParam),
static_cast<MakoOpenFlags>(msg.lParam));
break;
case MAKO_PLAY:
play();
break;
case MAKO_STOP:
close();
break;
case MAKO_EXIT:
close();
return;
}
}
}
void open(std::string* file, MakoOpenFlags open_flags)
{
file_playing = file;
is_midi = open_flags & OPEN_MIDI;
MCI_OPEN_PARMS open;
open.lpstrElementName = file_playing->c_str();
DWORD flags = MCI_OPEN_ELEMENT | MCI_WAIT;
if (is_midi) {
flags |= MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID;
open.lpstrDeviceType = (LPCSTR)MCI_DEVTYPE_SEQUENCER;
}
MCIERROR err = mciSendCommand(0, MCI_OPEN, flags, (DWORD_PTR)&open);
if (err) {
WARNING("MCI_OPEN failed: %s: %s",
file_playing->c_str(), mci_geterror(err));
return;
}
devid = open.wDeviceID;
}
void play()
{
MCI_PLAY_PARMS play;
play.dwCallback = (DWORD_PTR)hwnd_notify;
play.dwFrom = 0;
DWORD flags = MCI_FROM | MCI_NOTIFY;
MCIERROR err = mciSendCommand(devid, MCI_PLAY, flags, (DWORD_PTR)&play);
if (err)
WARNING("MCI_PLAY failed: %s", mci_geterror(err));
}
void close() {
if (devid) {
mciSendCommand(devid, MCI_CLOSE, 0, 0);
devid = 0;
}
if (file_playing) {
if (is_midi)
DeleteFile(file_playing->c_str()); // remove temporary file
delete file_playing;
file_playing = nullptr;
}
}
HWND hwnd_notify;
unsigned thread_id;
std::string* file_playing = nullptr;
bool is_midi;
MCIDEVICEID devid = 0;
};
MCIThread* mci_thread;
class Music {
public:
Music(const char* fname, int loop) : loops(loop) {
std::string* fname_str = new std::string(fname);
mci_thread->post_message(MAKO_OPEN, (WPARAM)fname_str, OPEN_CD);
mci_thread->post_message(MAKO_PLAY, 0, 0);
playing = true;
}
Music(std::unique_ptr<MAKOMidi> midi, int loop) : loops(loop ? 1 : 0) {
std::vector<uint8> smf = midi->generate_smf(loop);
char path[MAX_PATH + 1];
if (!GetTempPath(sizeof(path), path)) {
WARNING("GetTempPath failed: 0x%x", GetLastError());
return;
}
char fname[MAX_PATH + 1];
if (!GetTempFileName(path, "mid", 0, fname)) {
WARNING("GetTempFileName failed: 0x%x", GetLastError());
return;
}
FILE* fp = fopen(fname, "wb");
if (!fp) {
WARNING("Cannot open %s: %s", fname, strerror(errno));
return;
}
if (fwrite(smf.data(), smf.size(), 1, fp) != 1) {
WARNING("Cannot write to %s: %s", fname, strerror(errno));
fclose(fp);
DeleteFile(fname);
return;
}
fclose(fp);
std::string* fname_str = new std::string(fname);
mci_thread->post_message(MAKO_OPEN, (WPARAM)fname_str, OPEN_MIDI);
mci_thread->post_message(MAKO_PLAY, 0, 0);
playing = true;
}
~Music() {
close();
}
void close() {
mci_thread->post_message(MAKO_STOP, 0, 0);
playing = false;
}
bool is_playing() {
return playing;
}
bool on_mci_notify(const SDL_SysWMmsg* msg) {
if (msg->msg.win.lParam != mci_thread->device_id())
return true;
switch (msg->msg.win.wParam) {
case MCI_NOTIFY_FAILURE:
close();
return false;
case MCI_NOTIFY_SUCCESSFUL:
if (loops && --loops == 0) {
close();
return false;
}
mci_thread->post_message(MAKO_PLAY, 0, 0);
return true;
}
return true;
}
private:
int loops; // number of times to play, 0 for infinite loop
bool playing;
};
Music* music;
uint8* wav_buffer;
SDL_mutex* fm_mutex;
std::unique_ptr<MakoFMgen> fm;
void audio_callback(void*, Uint8* stream, int len) {
SDL_LockMutex(fm_mutex);
fm->Process(reinterpret_cast<int16*>(stream), len/ 4);
SDL_UnlockMutex(fm_mutex);
}
} // namespace
MAKO::MAKO(NACT* parent, const Config& config) :
use_fm(config.use_fm),
current_music(0),
next_loop(0),
nact(parent)
{
if (!config.playlist.empty())
load_playlist(config.playlist.c_str());
strcpy_s(amus, 16, "AMUS.DAT");
strcpy_s(amse, 16, "AMSE.DAT"); // 実際には使わない
for(int i = 1; i <= 99; i++) {
cd_track[i] = 0;
}
SDL_InitSubSystem(SDL_INIT_AUDIO);
SDL_AudioSpec fmt;
SDL_zero(fmt);
fmt.freq = SAMPLE_RATE;
fmt.format = AUDIO_S16;
fmt.channels = 2;
fmt.samples = 4096;
fmt.callback = &audio_callback;
if (SDL_OpenAudio(&fmt, NULL) < 0) {
WARNING("SDL_OpenAudio: %s", SDL_GetError());
use_fm = false;
}
fm_mutex = SDL_CreateMutex();
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
if (!SDL_GetWindowWMInfo(g_window, &info))
parent->fatal("SDL_GetWindowWMInfo failed: %s", SDL_GetError());
mci_thread = new MCIThread(parent, info.info.win.window);
}
MAKO::~MAKO()
{
stop_music();
stop_pcm();
mci_thread->post_message(MAKO_EXIT, 0, 0);
mci_thread = nullptr; // MCIThread self-destructs on the worker thread.
SDL_LockMutex(fm_mutex);
SDL_CloseAudio();
SDL_UnlockMutex(fm_mutex);
SDL_DestroyMutex(fm_mutex);
fm_mutex = nullptr;
SDL_QuitSubSystem(SDL_INIT_AUDIO);
}
bool MAKO::load_playlist(const char* path)
{
FILE* fp = fopen(path, "rt");
if (!fp) {
WARNING("Cannot open %s", path);
return false;
}
char buf[256];
while (fgets(buf, sizeof(buf) - 1, fp)) {
char *p = &buf[strlen(buf) - 1];
if (*p == '\n')
*p = '\0';
playlist.push_back(buf[0] ? strdup(buf) : NULL);
}
fclose(fp);
return true;
}
void MAKO::play_music(int page)
{
if (current_music == page)
return;
stop_music();
size_t track = page < 100 ? cd_track[page] : 0;
if (track) {
if (track >= playlist.size() || !playlist[track])
return;
music = new Music(playlist[track], next_loop);
} else if (use_fm) {
DRI dri;
int size;
uint8* data = dri.load(amus, page, &size);
if (!data)
return;
SDL_LockMutex(fm_mutex);
fm = std::make_unique<MakoFMgen>(SAMPLE_RATE, data, true);
SDL_UnlockMutex(fm_mutex);
SDL_PauseAudio(0);
} else {
auto midi = std::make_unique<MAKOMidi>(nact, amus);
if (!midi->load_mml(page))
return;
midi->load_mda(page);
music = new Music(std::move(midi), next_loop);
}
current_music = page;
}
void MAKO::stop_music()
{
if (music) {
delete music;
music = nullptr;
}
SDL_PauseAudio(1);
current_music = 0;
}
bool MAKO::check_music()
{
return music && music->is_playing();
}
void MAKO::select_sound(BGMDevice dev)
{
// 強制的に音源を変更する
int page = current_music;
int old_dev = (1 <= page && page <= 99 && cd_track[page]) ? BGM_CD :
use_fm ? BGM_FM : BGM_MIDI;
switch (dev) {
case BGM_FM:
case BGM_MIDI:
for (int i = 1; i <= 99; i++)
cd_track[i] = 0;
use_fm = dev == BGM_FM;
break;
case BGM_CD:
const int8* tracks;
switch (nact->crc32_a) {
case CRC32_RANCE41:
case CRC32_RANCE41_ENG:
tracks = RANCE41_tracks;
break;
case CRC32_RANCE42:
case CRC32_RANCE42_ENG:
tracks = RANCE42_tracks;
break;
case CRC32_DPSALL:
tracks = DPSALL_tracks;
break;
// For the following games, the default mapping (cd_track[i] = i) works.
case CRC32_AYUMI_CD:
case CRC32_FUNNYBEE_CD:
case CRC32_ONLYYOU:
default:
tracks = nullptr;
}
if (tracks) {
for (int i = 0; tracks[i] >= 0; i++)
cd_track[i + 1] = tracks[i];
} else {
for (int i = 1; i <= 99; i++)
cd_track[i] = i;
}
break;
}
// デバイスが変更された場合は再演奏する
if (dev != old_dev && page) {
stop_music();
play_music(page);
}
}
void MAKO::get_mark(int* mark, int* loop)
{
SDL_LockMutex(fm_mutex);
if (fm) {
fm->get_mark(mark, loop);
} else {
*mark = 0;
*loop = 0;
}
SDL_UnlockMutex(fm_mutex);
}
void MAKO::play_pcm(int page, bool loop)
{
static char header[44] = {
'R' , 'I' , 'F' , 'F' , 0x00, 0x00, 0x00, 0x00, 'W' , 'A' , 'V' , 'E' , 'f' , 'm' , 't' , ' ' ,
0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x40, 0x1f, 0x00, 0x00, 0x40, 0x1f, 0x00, 0x00,
0x01, 0x00, 0x08, 0x00, 'd' , 'a' , 't' , 'a' , 0x00, 0x00, 0x00, 0x00
};
stop_pcm();
uint8* buffer = NULL;
int size;
DRI* dri = new DRI();
if ((buffer = dri->load("AWAV.DAT", page, &size)) != NULL) {
// WAV形式 (Only You)
wav_buffer = buffer;
} else if ((buffer = dri->load("AMSE.DAT", page, &size)) != NULL) {
// AMSE形式 (乙女戦記)
int total = (size - 12) * 2 + 0x24;
int samples = (size - 12) * 2;
wav_buffer = (uint8*)malloc(total + 8);
memcpy(wav_buffer, header, 44);
wav_buffer[ 4] = (total >> 0) & 0xff;
wav_buffer[ 5] = (total >> 8) & 0xff;
wav_buffer[ 6] = (total >> 16) & 0xff;
wav_buffer[ 7] = (total >> 24) & 0xff;
wav_buffer[40] = (samples >> 0) & 0xff;
wav_buffer[41] = (samples >> 8) & 0xff;
wav_buffer[42] = (samples >> 16) & 0xff;
wav_buffer[43] = (samples >> 24) & 0xff;
for(int i = 12, p = 44; i < size; i++) {
wav_buffer[p++] = buffer[i] & 0xf0;
wav_buffer[p++] = (buffer[i] & 0x0f) << 4;
}
free(buffer);
}
PlaySound((LPCTSTR)wav_buffer, NULL, SND_ASYNC | SND_MEMORY | (loop ? SND_LOOP : 0));
}
void MAKO::stop_pcm()
{
PlaySound(NULL, NULL, SND_PURGE);
if (wav_buffer) {
free(wav_buffer);
wav_buffer = nullptr;
}
}
bool MAKO::check_pcm()
{
// 再生中でtrue
static const char null_wav[45] = {
'R' , 'I' , 'F' , 'F' , 0x25, 0x00, 0x00, 0x00, 'W' , 'A' , 'V' , 'E' , 'f' , 'm' , 't' , ' ' ,
0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x40, 0x1f, 0x00, 0x00, 0x40, 0x1f, 0x00, 0x00,
0x01, 0x00, 0x08, 0x00, 'd' , 'a' , 't' , 'a' , 0x01, 0x00, 0x00, 0x00, 0x00
};
return !PlaySound(null_wav, NULL, SND_ASYNC | SND_MEMORY | SND_NOSTOP);
}
void MAKO::on_mci_notify(const SDL_SysWMmsg* msg)
{
if (!music)
return;
if (!music->on_mci_notify(msg))
current_music = 0;
}
/*
ALICE SOFT SYSTEM 3 for Win32
[ MAKO ]
*/
#include <windows.h>
#undef ERROR
#include <memory>
#include <string>
#include <SDL.h>
#include <SDL_syswm.h>
#include "mako.h"
#include "mako_midi.h"
#include "fm/mako_fmgen.h"
#include "../config.h"
#include "dri.h"
#include "crc32.h"
extern SDL_Window* g_window;
namespace {
const int SAMPLE_RATE = 44100;
// Per-game mapping from music numbers to CD tracks. This is necessary to
// forcibly change the sound device with a menu command.
//
// When the game uses "Z 100+x,y" command, the xth element of the array should
// be y. The array must be terminated with -1.
const int8 RANCE41_tracks[] = {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,1,-1};
const int8 RANCE42_tracks[] = {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,1,-1};
const int8 DPSALL_tracks[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,5,1,2,3,-1};
enum MakoThreadMessage {
MAKO_OPEN = WM_APP,
MAKO_PLAY,
MAKO_STOP,
MAKO_EXIT
};
enum MakoOpenFlags {
OPEN_CD = 0,
OPEN_MIDI = 1,
};
const char* mci_geterror(DWORD err)
{
static char buf[128];
mciGetErrorString(err, buf, sizeof(buf));
return buf;
}
class MCIThread {
public:
MCIThread(NACT* nact, HWND hwnd_notify) : hwnd_notify(hwnd_notify) {
if (!_beginthreadex(NULL, 0, &MCIThread::run, this, 0, &thread_id))
nact->fatal("Cannot create thread: %s", strerror(errno));
}
bool post_message(UINT msg, WPARAM wparam, LPARAM lparam) {
return PostThreadMessage(thread_id, msg, wparam, lparam);
}
MCIDEVICEID device_id() { return devid; }
private:
static unsigned __stdcall run(void* param)
{
MCIThread* t = reinterpret_cast<MCIThread*>(param);
t->message_loop();
delete t;
return 0;
}
void message_loop()
{
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
switch (msg.message) {
case MAKO_OPEN:
close();
open(reinterpret_cast<std::string*>(msg.wParam),
static_cast<MakoOpenFlags>(msg.lParam));
break;
case MAKO_PLAY:
play();
break;
case MAKO_STOP:
close();
break;
case MAKO_EXIT:
close();
return;
}
}
}
void open(std::string* file, MakoOpenFlags open_flags)
{
file_playing = file;
is_midi = open_flags & OPEN_MIDI;
MCI_OPEN_PARMS open;
open.lpstrElementName = file_playing->c_str();
DWORD flags = MCI_OPEN_ELEMENT | MCI_WAIT;
if (is_midi) {
flags |= MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID;
open.lpstrDeviceType = (LPCSTR)MCI_DEVTYPE_SEQUENCER;
}
MCIERROR err = mciSendCommand(0, MCI_OPEN, flags, (DWORD_PTR)&open);
if (err) {
WARNING("MCI_OPEN failed: %s: %s",
file_playing->c_str(), mci_geterror(err));
return;
}
devid = open.wDeviceID;
}
void play()
{
MCI_PLAY_PARMS play;
play.dwCallback = (DWORD_PTR)hwnd_notify;
play.dwFrom = 0;
DWORD flags = MCI_FROM | MCI_NOTIFY;
MCIERROR err = mciSendCommand(devid, MCI_PLAY, flags, (DWORD_PTR)&play);
if (err)
WARNING("MCI_PLAY failed: %s", mci_geterror(err));
}
void close() {
if (devid) {
mciSendCommand(devid, MCI_CLOSE, 0, 0);
devid = 0;
}
if (file_playing) {
if (is_midi)
DeleteFile(file_playing->c_str()); // remove temporary file
delete file_playing;
file_playing = nullptr;
}
}
HWND hwnd_notify;
unsigned thread_id;
std::string* file_playing = nullptr;
bool is_midi;
MCIDEVICEID devid = 0;
};
MCIThread* mci_thread;
class Music {
public:
Music(const char* fname, int loop) : loops(loop) {
std::string* fname_str = new std::string(fname);
mci_thread->post_message(MAKO_OPEN, (WPARAM)fname_str, OPEN_CD);
mci_thread->post_message(MAKO_PLAY, 0, 0);
playing = true;
}
Music(std::unique_ptr<MAKOMidi> midi, int loop) : loops(loop ? 1 : 0) {
std::vector<uint8> smf = midi->generate_smf(loop);
char path[MAX_PATH + 1];
if (!GetTempPath(sizeof(path), path)) {
WARNING("GetTempPath failed: 0x%x", GetLastError());
return;
}
char fname[MAX_PATH + 1];
if (!GetTempFileName(path, "mid", 0, fname)) {
WARNING("GetTempFileName failed: 0x%x", GetLastError());
return;
}
FILE* fp = fopen(fname, "wb");
if (!fp) {
WARNING("Cannot open %s: %s", fname, strerror(errno));
return;
}
if (fwrite(smf.data(), smf.size(), 1, fp) != 1) {
WARNING("Cannot write to %s: %s", fname, strerror(errno));
fclose(fp);
DeleteFile(fname);
return;
}
fclose(fp);
std::string* fname_str = new std::string(fname);
mci_thread->post_message(MAKO_OPEN, (WPARAM)fname_str, OPEN_MIDI);
mci_thread->post_message(MAKO_PLAY, 0, 0);
playing = true;
}
~Music() {
close();
}
void close() {
mci_thread->post_message(MAKO_STOP, 0, 0);
playing = false;
}
bool is_playing() {
return playing;
}
bool on_mci_notify(const SDL_SysWMmsg* msg) {
if (msg->msg.win.lParam != mci_thread->device_id())
return true;
switch (msg->msg.win.wParam) {
case MCI_NOTIFY_FAILURE:
close();
return false;
case MCI_NOTIFY_SUCCESSFUL:
if (loops && --loops == 0) {
close();
return false;
}
mci_thread->post_message(MAKO_PLAY, 0, 0);
return true;
}
return true;
}
private:
int loops; // number of times to play, 0 for infinite loop
bool playing;
};
Music* music;
uint8* wav_buffer;
SDL_mutex* fm_mutex;
std::unique_ptr<MakoFMgen> fm;
void audio_callback(void*, Uint8* stream, int len) {
SDL_LockMutex(fm_mutex);
fm->Process(reinterpret_cast<int16*>(stream), len/ 4);
SDL_UnlockMutex(fm_mutex);
}
} // namespace
MAKO::MAKO(NACT* parent, const Config& config) :
use_fm(config.use_fm),
current_music(0),
next_loop(0),
nact(parent)
{
if (!config.playlist.empty())
load_playlist(config.playlist.c_str());
strcpy_s(amus, 16, "AMUS.DAT");
strcpy_s(amse, 16, "AMSE.DAT"); // 実際には使わない
for(int i = 1; i <= 99; i++) {
cd_track[i] = 0;
}
SDL_InitSubSystem(SDL_INIT_AUDIO);
SDL_AudioSpec fmt;
SDL_zero(fmt);
fmt.freq = SAMPLE_RATE;
fmt.format = AUDIO_S16;
fmt.channels = 2;
fmt.samples = 4096;
fmt.callback = &audio_callback;
if (SDL_OpenAudio(&fmt, NULL) < 0) {
WARNING("SDL_OpenAudio: %s", SDL_GetError());
use_fm = false;
}
fm_mutex = SDL_CreateMutex();
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
if (!SDL_GetWindowWMInfo(g_window, &info))
parent->fatal("SDL_GetWindowWMInfo failed: %s", SDL_GetError());
mci_thread = new MCIThread(parent, info.info.win.window);
}
MAKO::~MAKO()
{
stop_music();
stop_pcm();
mci_thread->post_message(MAKO_EXIT, 0, 0);
mci_thread = nullptr; // MCIThread self-destructs on the worker thread.
SDL_LockMutex(fm_mutex);
SDL_CloseAudio();
SDL_UnlockMutex(fm_mutex);
SDL_DestroyMutex(fm_mutex);
fm_mutex = nullptr;
SDL_QuitSubSystem(SDL_INIT_AUDIO);
}
bool MAKO::load_playlist(const char* path)
{
FILE* fp = fopen(path, "rt");
if (!fp) {
WARNING("Cannot open %s", path);
return false;
}
char buf[256];
while (fgets(buf, sizeof(buf) - 1, fp)) {
char *p = &buf[strlen(buf) - 1];
if (*p == '\n')
*p = '\0';
playlist.push_back(buf[0] ? strdup(buf) : NULL);
}
fclose(fp);
return true;
}
void MAKO::play_music(int page)
{
if (current_music == page)
return;
stop_music();
size_t track = page < 100 ? cd_track[page] : 0;
if (track) {
if (track >= playlist.size() || !playlist[track])
return;
music = new Music(playlist[track], next_loop);
} else if (use_fm) {
DRI dri;
int size;
uint8* data = dri.load(amus, page, &size);
if (!data)
return;
SDL_LockMutex(fm_mutex);
fm = std::make_unique<MakoFMgen>(SAMPLE_RATE, data, true);
SDL_UnlockMutex(fm_mutex);
SDL_PauseAudio(0);
} else {
auto midi = std::make_unique<MAKOMidi>(nact, amus);
if (!midi->load_mml(page))
return;
midi->load_mda(page);
music = new Music(std::move(midi), next_loop);
}
current_music = page;
}
void MAKO::stop_music()
{
if (music) {
delete music;
music = nullptr;
}
SDL_PauseAudio(1);
current_music = 0;
}
bool MAKO::check_music()
{
return music && music->is_playing();
}
void MAKO::select_sound(BGMDevice dev)
{
// 強制的に音源を変更する
int page = current_music;
int old_dev = (1 <= page && page <= 99 && cd_track[page]) ? BGM_CD :
use_fm ? BGM_FM : BGM_MIDI;
switch (dev) {
case BGM_FM:
case BGM_MIDI:
for (int i = 1; i <= 99; i++)
cd_track[i] = 0;
use_fm = dev == BGM_FM;
break;
case BGM_CD:
const int8* tracks;
switch (nact->crc32_a) {
case CRC32_RANCE41:
case CRC32_RANCE41_ENG:
tracks = RANCE41_tracks;
break;
case CRC32_RANCE42:
case CRC32_RANCE42_ENG:
tracks = RANCE42_tracks;
break;
case CRC32_DPSALL:
tracks = DPSALL_tracks;
break;
// For the following games, the default mapping (cd_track[i] = i) works.
case CRC32_AYUMI_CD:
case CRC32_FUNNYBEE_CD:
case CRC32_ONLYYOU:
default:
tracks = nullptr;
}
if (tracks) {
for (int i = 0; tracks[i] >= 0; i++)
cd_track[i + 1] = tracks[i];
} else {
for (int i = 1; i <= 99; i++)
cd_track[i] = i;
}
break;
}
// デバイスが変更された場合は再演奏する
if (dev != old_dev && page) {
stop_music();
play_music(page);
}
}
void MAKO::get_mark(int* mark, int* loop)
{
SDL_LockMutex(fm_mutex);
if (fm) {
fm->get_mark(mark, loop);
} else {
*mark = 0;
*loop = 0;
}
SDL_UnlockMutex(fm_mutex);
}
void MAKO::play_pcm(int page, bool loop)
{
static char header[44] = {
'R' , 'I' , 'F' , 'F' , 0x00, 0x00, 0x00, 0x00, 'W' , 'A' , 'V' , 'E' , 'f' , 'm' , 't' , ' ' ,
0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x40, 0x1f, 0x00, 0x00, 0x40, 0x1f, 0x00, 0x00,
0x01, 0x00, 0x08, 0x00, 'd' , 'a' , 't' , 'a' , 0x00, 0x00, 0x00, 0x00
};
stop_pcm();
uint8* buffer = NULL;
int size;
DRI* dri = new DRI();
if ((buffer = dri->load("AWAV.DAT", page, &size)) != NULL) {
// WAV形式 (Only You)
wav_buffer = buffer;
} else if ((buffer = dri->load("AMSE.DAT", page, &size)) != NULL) {
// AMSE形式 (乙女戦記)
int total = (size - 12) * 2 + 0x24;
int samples = (size - 12) * 2;
wav_buffer = (uint8*)malloc(total + 8);
memcpy(wav_buffer, header, 44);
wav_buffer[ 4] = (total >> 0) & 0xff;
wav_buffer[ 5] = (total >> 8) & 0xff;
wav_buffer[ 6] = (total >> 16) & 0xff;
wav_buffer[ 7] = (total >> 24) & 0xff;
wav_buffer[40] = (samples >> 0) & 0xff;
wav_buffer[41] = (samples >> 8) & 0xff;
wav_buffer[42] = (samples >> 16) & 0xff;
wav_buffer[43] = (samples >> 24) & 0xff;
for(int i = 12, p = 44; i < size; i++) {
wav_buffer[p++] = buffer[i] & 0xf0;
wav_buffer[p++] = (buffer[i] & 0x0f) << 4;
}
free(buffer);
}
PlaySound((LPCTSTR)wav_buffer, NULL, SND_ASYNC | SND_MEMORY | (loop ? SND_LOOP : 0));
}
void MAKO::stop_pcm()
{
PlaySound(NULL, NULL, SND_PURGE);
if (wav_buffer) {
free(wav_buffer);
wav_buffer = nullptr;
}
}
bool MAKO::check_pcm()
{
// 再生中でtrue
static const char null_wav[45] = {
'R' , 'I' , 'F' , 'F' , 0x25, 0x00, 0x00, 0x00, 'W' , 'A' , 'V' , 'E' , 'f' , 'm' , 't' , ' ' ,
0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x40, 0x1f, 0x00, 0x00, 0x40, 0x1f, 0x00, 0x00,
0x01, 0x00, 0x08, 0x00, 'd' , 'a' , 't' , 'a' , 0x01, 0x00, 0x00, 0x00, 0x00
};
return !PlaySound(null_wav, NULL, SND_ASYNC | SND_MEMORY | SND_NOSTOP);
}
void MAKO::on_mci_notify(const SDL_SysWMmsg* msg)
{
if (!music)
return;
if (!music->on_mci_notify(msg))
current_music = 0;
}
+33 -33
View File
@@ -1,33 +1,33 @@
#ifndef _RESOURCE_H_
#define _RESOURCE_H_
#define IDR_MENU1 101
#define IDI_ICON1 102
#define IDD_DIALOG1 103
#define IDC_TEXT 104
#define IDC_EDITBOX 105
#define IDR_AL3 106
#define IDR_ALL 107
#define IDR_AMB 108
#define IDR_AYM 109
#define IDR_BEE 110
#define IDR_MGN 111
#define IDR_OTM 112
#define IDR_OY 113
#define IDR_PSG 114
#define IDR_R41 115
#define IDR_R42 116
#define IDR_RG2 117
#define IDR_T2 118
#define ID_SCREENSHOT 40000
#define ID_RESTART 40001
#define ID_EXIT 40002
#define ID_SCREEN_WINDOW 40003
#define ID_SCREEN_FULL 40004
#define ID_SOUND_FM 40005
#define ID_SOUND_MIDI 40006
#define ID_SOUND_CD 40007
#define ID_TEXT_SKIP 40008
#define ID_TEXT_WAIT 40009
#endif // _RESOURCE_H_
#ifndef _RESOURCE_H_
#define _RESOURCE_H_
#define IDR_MENU1 101
#define IDI_ICON1 102
#define IDD_DIALOG1 103
#define IDC_TEXT 104
#define IDC_EDITBOX 105
#define IDR_AL3 106
#define IDR_ALL 107
#define IDR_AMB 108
#define IDR_AYM 109
#define IDR_BEE 110
#define IDR_MGN 111
#define IDR_OTM 112
#define IDR_OY 113
#define IDR_PSG 114
#define IDR_R41 115
#define IDR_R42 116
#define IDR_RG2 117
#define IDR_T2 118
#define ID_SCREENSHOT 40000
#define ID_RESTART 40001
#define ID_EXIT 40002
#define ID_SCREEN_WINDOW 40003
#define ID_SCREEN_FULL 40004
#define ID_SOUND_FM 40005
#define ID_SOUND_MIDI 40006
#define ID_SOUND_CD 40007
#define ID_TEXT_SKIP 40008
#define ID_TEXT_WAIT 40009
#endif // _RESOURCE_H_
+235 -235
View File
@@ -1,235 +1,235 @@
#pragma code_page(65001)
#include "resource.h"
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON1 ICON DISCARDABLE "icon1.ico"
/////////////////////////////////////////////////////////////////////////////
//
// FONTS
//
// Note for game translators:
// Rather than replacing this, use a separate font file and the "fontfile"
// option in system3.ini. That will allow your translated version run on
// other platforms, such as Android and Web.
MTLc3m.ttf FONTS DISCARDABLE "../../resources/fonts/MTLc3m.ttf"
/////////////////////////////////////////////////////////////////////////////
//
// MDA
//
AMUS_AB.MDA MDA DISCARDABLE "../../resources/mda/AMUS_AB.MDA"
AMUS_AL1.MDA MDA DISCARDABLE "../../resources/mda/AMUS_AL1.MDA"
AMUS_AL2.MDA MDA DISCARDABLE "../../resources/mda/AMUS_AL2.MDA"
AMUS_AL3.MDA MDA DISCARDABLE "../../resources/mda/AMUS_AL3.MDA"
AMUS_ALL.MDA MDA DISCARDABLE "../../resources/mda/AMUS_ALL.MDA"
AMUS_AMB.MDA MDA DISCARDABLE "../../resources/mda/AMUS_AMB.MDA"
AMUS_AT.MDA MDA DISCARDABLE "../../resources/mda/AMUS_AT.MDA"
AMUS_AYM.MDA MDA DISCARDABLE "../../resources/mda/AMUS_AYM.MDA"
AMUS_BEE.MDA MDA DISCARDABLE "../../resources/mda/AMUS_BEE.MDA"
AMUS_CRS.MDA MDA DISCARDABLE "../../resources/mda/AMUS_CRS.MDA"
AMUS_DLK.MDA MDA DISCARDABLE "../../resources/mda/AMUS_DLK.MDA"
AMUS_DPS.MDA MDA DISCARDABLE "../../resources/mda/AMUS_DPS.MDA"
AMUS_DRS.MDA MDA DISCARDABLE "../../resources/mda/AMUS_DRS.MDA"
AMUS_INT.MDA MDA DISCARDABLE "../../resources/mda/AMUS_INT.MDA"
AMUS_KNG.MDA MDA DISCARDABLE "../../resources/mda/AMUS_KNG.MDA"
AMUS_LP2.MDA MDA DISCARDABLE "../../resources/mda/AMUS_LP2.MDA"
AMUS_MGN.MDA MDA DISCARDABLE "../../resources/mda/AMUS_MGN.MDA"
AMUS_OTM.MDA MDA DISCARDABLE "../../resources/mda/AMUS_OTM.MDA"
AMUS_OY.MDA MDA DISCARDABLE "../../resources/mda/AMUS_OY.MDA"
AMUS_PSG.MDA MDA DISCARDABLE "../../resources/mda/AMUS_PSG.MDA"
AMUS_R3H.MDA MDA DISCARDABLE "../../resources/mda/AMUS_R3H.MDA"
AMUS_R4.MDA MDA DISCARDABLE "../../resources/mda/AMUS_R4.MDA"
AMUS_R41.MDA MDA DISCARDABLE "../../resources/mda/AMUS_R41.MDA"
AMUS_R42.MDA MDA DISCARDABLE "../../resources/mda/AMUS_R42.MDA"
AMUS_RG2.MDA MDA DISCARDABLE "../../resources/mda/AMUS_RG2.MDA"
AMUS_SDP.MDA MDA DISCARDABLE "../../resources/mda/AMUS_SDP.MDA"
AMUS_SG.MDA MDA DISCARDABLE "../../resources/mda/AMUS_SG.MDA"
AMUS_T1.MDA MDA DISCARDABLE "../../resources/mda/AMUS_T1.MDA"
AMUS_T2.MDA MDA DISCARDABLE "../../resources/mda/AMUS_T2.MDA"
AMUS_VX.MDA MDA DISCARDABLE "../../resources/mda/AMUS_VX.MDA"
BMUS_AKA.MDA MDA DISCARDABLE "../../resources/mda/BMUS_AKA.MDA"
BMUS_ANT.MDA MDA DISCARDABLE "../../resources/mda/BMUS_ANT.MDA"
BMUS_FAH.MDA MDA DISCARDABLE "../../resources/mda/BMUS_FAH.MDA"
BMUS_KAM.MDA MDA DISCARDABLE "../../resources/mda/BMUS_KAM.MDA"
BMUS_KAT.MDA MDA DISCARDABLE "../../resources/mda/BMUS_KAT.MDA"
BMUS_MTK.MDA MDA DISCARDABLE "../../resources/mda/BMUS_MTK.MDA"
BMUS_NAI.MDA MDA DISCARDABLE "../../resources/mda/BMUS_NAI.MDA"
BMUS_NOB.MDA MDA DISCARDABLE "../../resources/mda/BMUS_NOB.MDA"
BMUS_RAB.MDA MDA DISCARDABLE "../../resources/mda/BMUS_RAB.MDA"
BMUS_SIN.MDA MDA DISCARDABLE "../../resources/mda/BMUS_SIN.MDA"
BMUS_SOT.MDA MDA DISCARDABLE "../../resources/mda/BMUS_SOT.MDA"
BMUS_TNM.MDA MDA DISCARDABLE "../../resources/mda/BMUS_TNM.MDA"
CMUS_T1.MDA MDA DISCARDABLE "../../resources/mda/CMUS_T1.MDA"
/////////////////////////////////////////////////////////////////////////////
// English resources
LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDR_MENU1 MENU DISCARDABLE
BEGIN
POPUP "File"
BEGIN
MENUITEM "Save Screenshot", ID_SCREENSHOT
MENUITEM SEPARATOR
MENUITEM "Restart", ID_RESTART
MENUITEM SEPARATOR
MENUITEM "Exit", ID_EXIT
END
POPUP "Screen"
BEGIN
MENUITEM "Window", ID_SCREEN_WINDOW
MENUITEM "Fullscreen", ID_SCREEN_FULL
END
POPUP "Sound"
BEGIN
MENUITEM "FM Sound", ID_SOUND_FM
MENUITEM "MIDI Sound", ID_SOUND_MIDI
MENUITEM "CD Audio", ID_SOUND_CD
END
POPUP "Message"
BEGIN
MENUITEM "Skip", ID_TEXT_SKIP
MENUITEM "Wait", ID_TEXT_WAIT
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 122, 55
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Text input"
FONT 9, "MS Shell Dlg"
BEGIN
EDITTEXT IDC_EDITBOX,7,15,112,12
LTEXT "Enter a string (up to 8 letters)",IDC_TEXT,7,3,112,8
DEFPUSHBUTTON "OK",IDOK,35,36,50,14
END
/////////////////////////////////////////////////////////////////////////////
// 日本語 resources
LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDR_MENU1 MENU DISCARDABLE
BEGIN
POPUP "ファイル"
BEGIN
MENUITEM "画面保存", ID_SCREENSHOT
MENUITEM SEPARATOR
MENUITEM "再起動", ID_RESTART
MENUITEM SEPARATOR
MENUITEM "閉じる", ID_EXIT
END
POPUP "画面"
BEGIN
MENUITEM "ウィンドウ", ID_SCREEN_WINDOW
MENUITEM "フルスクリーン", ID_SCREEN_FULL
END
POPUP "サウンド"
BEGIN
MENUITEM "FM音源", ID_SOUND_FM
MENUITEM "MIDI音源", ID_SOUND_MIDI
MENUITEM "CD音源", ID_SOUND_CD
END
POPUP "メッセージ"
BEGIN
MENUITEM "スキップ", ID_TEXT_SKIP
MENUITEM "ウェイトあり", ID_TEXT_WAIT
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 122, 55
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "文字列の入力"
FONT 9, "MS Pゴシック"
BEGIN
EDITTEXT IDC_EDITBOX,7,15,112,12
LTEXT "文字を入力してください(最大8文字)",IDC_TEXT,7,3,112,8
DEFPUSHBUTTON "OK",IDOK,35,36,50,14
END
/////////////////////////////////////////////////////////////////////////////
// 简体中文 resources
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDR_MENU1 MENU DISCARDABLE
BEGIN
POPUP "文件"
BEGIN
MENUITEM "截图", ID_SCREENSHOT
MENUITEM SEPARATOR
MENUITEM "重启", ID_RESTART
MENUITEM SEPARATOR
MENUITEM "退出", ID_EXIT
END
POPUP "窗口"
BEGIN
MENUITEM "窗口化", ID_SCREEN_WINDOW
MENUITEM "全屏化", ID_SCREEN_FULL
END
POPUP "音源"
BEGIN
MENUITEM "FM 音源", ID_SOUND_FM
MENUITEM "MIDI 音源", ID_SOUND_MIDI
MENUITEM "CD 音源", ID_SOUND_CD
END
POPUP "消息"
BEGIN
MENUITEM "跳过", ID_TEXT_SKIP
MENUITEM "等待", ID_TEXT_WAIT
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 122, 55
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "字符串输入"
FONT 9, "微软雅黑"
BEGIN
EDITTEXT IDC_EDITBOX,7,15,112,12
LTEXT "请输入字符串(最多8个字符)",IDC_TEXT,7,3,112,8
DEFPUSHBUTTON "OK",IDOK,35,36,50,14
END
#pragma code_page(65001)
#include "resource.h"
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON1 ICON DISCARDABLE "icon1.ico"
/////////////////////////////////////////////////////////////////////////////
//
// FONTS
//
// Note for game translators:
// Rather than replacing this, use a separate font file and the "fontfile"
// option in system3.ini. That will allow your translated version run on
// other platforms, such as Android and Web.
MTLc3m.ttf FONTS DISCARDABLE "../../resources/fonts/MTLc3m.ttf"
/////////////////////////////////////////////////////////////////////////////
//
// MDA
//
AMUS_AB.MDA MDA DISCARDABLE "../../resources/mda/AMUS_AB.MDA"
AMUS_AL1.MDA MDA DISCARDABLE "../../resources/mda/AMUS_AL1.MDA"
AMUS_AL2.MDA MDA DISCARDABLE "../../resources/mda/AMUS_AL2.MDA"
AMUS_AL3.MDA MDA DISCARDABLE "../../resources/mda/AMUS_AL3.MDA"
AMUS_ALL.MDA MDA DISCARDABLE "../../resources/mda/AMUS_ALL.MDA"
AMUS_AMB.MDA MDA DISCARDABLE "../../resources/mda/AMUS_AMB.MDA"
AMUS_AT.MDA MDA DISCARDABLE "../../resources/mda/AMUS_AT.MDA"
AMUS_AYM.MDA MDA DISCARDABLE "../../resources/mda/AMUS_AYM.MDA"
AMUS_BEE.MDA MDA DISCARDABLE "../../resources/mda/AMUS_BEE.MDA"
AMUS_CRS.MDA MDA DISCARDABLE "../../resources/mda/AMUS_CRS.MDA"
AMUS_DLK.MDA MDA DISCARDABLE "../../resources/mda/AMUS_DLK.MDA"
AMUS_DPS.MDA MDA DISCARDABLE "../../resources/mda/AMUS_DPS.MDA"
AMUS_DRS.MDA MDA DISCARDABLE "../../resources/mda/AMUS_DRS.MDA"
AMUS_INT.MDA MDA DISCARDABLE "../../resources/mda/AMUS_INT.MDA"
AMUS_KNG.MDA MDA DISCARDABLE "../../resources/mda/AMUS_KNG.MDA"
AMUS_LP2.MDA MDA DISCARDABLE "../../resources/mda/AMUS_LP2.MDA"
AMUS_MGN.MDA MDA DISCARDABLE "../../resources/mda/AMUS_MGN.MDA"
AMUS_OTM.MDA MDA DISCARDABLE "../../resources/mda/AMUS_OTM.MDA"
AMUS_OY.MDA MDA DISCARDABLE "../../resources/mda/AMUS_OY.MDA"
AMUS_PSG.MDA MDA DISCARDABLE "../../resources/mda/AMUS_PSG.MDA"
AMUS_R3H.MDA MDA DISCARDABLE "../../resources/mda/AMUS_R3H.MDA"
AMUS_R4.MDA MDA DISCARDABLE "../../resources/mda/AMUS_R4.MDA"
AMUS_R41.MDA MDA DISCARDABLE "../../resources/mda/AMUS_R41.MDA"
AMUS_R42.MDA MDA DISCARDABLE "../../resources/mda/AMUS_R42.MDA"
AMUS_RG2.MDA MDA DISCARDABLE "../../resources/mda/AMUS_RG2.MDA"
AMUS_SDP.MDA MDA DISCARDABLE "../../resources/mda/AMUS_SDP.MDA"
AMUS_SG.MDA MDA DISCARDABLE "../../resources/mda/AMUS_SG.MDA"
AMUS_T1.MDA MDA DISCARDABLE "../../resources/mda/AMUS_T1.MDA"
AMUS_T2.MDA MDA DISCARDABLE "../../resources/mda/AMUS_T2.MDA"
AMUS_VX.MDA MDA DISCARDABLE "../../resources/mda/AMUS_VX.MDA"
BMUS_AKA.MDA MDA DISCARDABLE "../../resources/mda/BMUS_AKA.MDA"
BMUS_ANT.MDA MDA DISCARDABLE "../../resources/mda/BMUS_ANT.MDA"
BMUS_FAH.MDA MDA DISCARDABLE "../../resources/mda/BMUS_FAH.MDA"
BMUS_KAM.MDA MDA DISCARDABLE "../../resources/mda/BMUS_KAM.MDA"
BMUS_KAT.MDA MDA DISCARDABLE "../../resources/mda/BMUS_KAT.MDA"
BMUS_MTK.MDA MDA DISCARDABLE "../../resources/mda/BMUS_MTK.MDA"
BMUS_NAI.MDA MDA DISCARDABLE "../../resources/mda/BMUS_NAI.MDA"
BMUS_NOB.MDA MDA DISCARDABLE "../../resources/mda/BMUS_NOB.MDA"
BMUS_RAB.MDA MDA DISCARDABLE "../../resources/mda/BMUS_RAB.MDA"
BMUS_SIN.MDA MDA DISCARDABLE "../../resources/mda/BMUS_SIN.MDA"
BMUS_SOT.MDA MDA DISCARDABLE "../../resources/mda/BMUS_SOT.MDA"
BMUS_TNM.MDA MDA DISCARDABLE "../../resources/mda/BMUS_TNM.MDA"
CMUS_T1.MDA MDA DISCARDABLE "../../resources/mda/CMUS_T1.MDA"
/////////////////////////////////////////////////////////////////////////////
// English resources
LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDR_MENU1 MENU DISCARDABLE
BEGIN
POPUP "File"
BEGIN
MENUITEM "Save Screenshot", ID_SCREENSHOT
MENUITEM SEPARATOR
MENUITEM "Restart", ID_RESTART
MENUITEM SEPARATOR
MENUITEM "Exit", ID_EXIT
END
POPUP "Screen"
BEGIN
MENUITEM "Window", ID_SCREEN_WINDOW
MENUITEM "Fullscreen", ID_SCREEN_FULL
END
POPUP "Sound"
BEGIN
MENUITEM "FM Sound", ID_SOUND_FM
MENUITEM "MIDI Sound", ID_SOUND_MIDI
MENUITEM "CD Audio", ID_SOUND_CD
END
POPUP "Message"
BEGIN
MENUITEM "Skip", ID_TEXT_SKIP
MENUITEM "Wait", ID_TEXT_WAIT
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 122, 55
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Text input"
FONT 9, "MS Shell Dlg"
BEGIN
EDITTEXT IDC_EDITBOX,7,15,112,12
LTEXT "Enter a string (up to 8 letters)",IDC_TEXT,7,3,112,8
DEFPUSHBUTTON "OK",IDOK,35,36,50,14
END
/////////////////////////////////////////////////////////////////////////////
// 日本語 resources
LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDR_MENU1 MENU DISCARDABLE
BEGIN
POPUP "ファイル"
BEGIN
MENUITEM "画面保存", ID_SCREENSHOT
MENUITEM SEPARATOR
MENUITEM "再起動", ID_RESTART
MENUITEM SEPARATOR
MENUITEM "閉じる", ID_EXIT
END
POPUP "画面"
BEGIN
MENUITEM "ウィンドウ", ID_SCREEN_WINDOW
MENUITEM "フルスクリーン", ID_SCREEN_FULL
END
POPUP "サウンド"
BEGIN
MENUITEM "FM音源", ID_SOUND_FM
MENUITEM "MIDI音源", ID_SOUND_MIDI
MENUITEM "CD音源", ID_SOUND_CD
END
POPUP "メッセージ"
BEGIN
MENUITEM "スキップ", ID_TEXT_SKIP
MENUITEM "ウェイトあり", ID_TEXT_WAIT
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 122, 55
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "文字列の入力"
FONT 9, "MS Pゴシック"
BEGIN
EDITTEXT IDC_EDITBOX,7,15,112,12
LTEXT "文字を入力してください(最大8文字)",IDC_TEXT,7,3,112,8
DEFPUSHBUTTON "OK",IDOK,35,36,50,14
END
/////////////////////////////////////////////////////////////////////////////
// 简体中文 resources
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDR_MENU1 MENU DISCARDABLE
BEGIN
POPUP "文件"
BEGIN
MENUITEM "截图", ID_SCREENSHOT
MENUITEM SEPARATOR
MENUITEM "重启", ID_RESTART
MENUITEM SEPARATOR
MENUITEM "退出", ID_EXIT
END
POPUP "窗口"
BEGIN
MENUITEM "窗口化", ID_SCREEN_WINDOW
MENUITEM "全屏化", ID_SCREEN_FULL
END
POPUP "音源"
BEGIN
MENUITEM "FM 音源", ID_SOUND_FM
MENUITEM "MIDI 音源", ID_SOUND_MIDI
MENUITEM "CD 音源", ID_SOUND_CD
END
POPUP "消息"
BEGIN
MENUITEM "跳过", ID_TEXT_SKIP
MENUITEM "等待", ID_TEXT_WAIT
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 122, 55
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "字符串输入"
FONT 9, "微软雅黑"
BEGIN
EDITTEXT IDC_EDITBOX,7,15,112,12
LTEXT "请输入字符串(最多8个字符)",IDC_TEXT,7,3,112,8
DEFPUSHBUTTON "OK",IDOK,35,36,50,14
END