1
zero-epwing-go/subbook.c

1115 lines
30 KiB
C
Raw Normal View History

2021-01-09 22:39:52 +00:00
/*
* Copyright (c) 1997-2006 Motoyuki Kasahara
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "build-pre.h"
#include "eb.h"
#include "error.h"
#include "binary.h"
#include "font.h"
#include "build-post.h"
/*
* Unexported functions.
*/
static EB_Error_Code eb_load_subbook(EB_Book *book);
static EB_Error_Code eb_load_subbook_indexes(EB_Book *book);
static EB_Error_Code eb_set_subbook_eb(EB_Book *book,
EB_Subbook_Code subbook_code);
static EB_Error_Code eb_set_subbook_epwing(EB_Book *book,
EB_Subbook_Code subbook_code);
/*
* Initialize all subbooks in `book'.
*/
void
eb_initialize_subbooks(EB_Book *book)
{
EB_Subbook *subbook;
EB_Subbook *saved_subbook_current;
int i;
LOG(("in: eb_initialize_subbooks(book=%d)", (int)book->code));
saved_subbook_current = book->subbook_current;
for (i = 0, subbook = book->subbooks; i < book->subbook_count;
2021-01-09 23:22:43 +00:00
i++, subbook++) {
book->subbook_current = subbook;
2021-01-09 22:39:52 +00:00
subbook->initialized = 0;
2021-01-09 23:22:43 +00:00
subbook->index_page = 1;
2021-01-09 22:39:52 +00:00
subbook->code = i;
zio_initialize(&subbook->text_zio);
zio_initialize(&subbook->graphic_zio);
zio_initialize(&subbook->sound_zio);
zio_initialize(&subbook->movie_zio);
subbook->title[0] = '\0';
subbook->directory_name[0] = '\0';
subbook->data_directory_name[0] = '\0';
subbook->gaiji_directory_name[0] = '\0';
subbook->movie_directory_name[0] = '\0';
subbook->text_file_name[0] = '\0';
subbook->graphic_file_name[0] = '\0';
subbook->sound_file_name[0] = '\0';
2021-01-09 23:22:43 +00:00
subbook->text_hint_zio_code = ZIO_PLAIN;
subbook->graphic_hint_zio_code = ZIO_PLAIN;
subbook->sound_hint_zio_code = ZIO_PLAIN;
2021-01-09 22:39:52 +00:00
2021-01-09 23:22:43 +00:00
subbook->search_title_page = 0;
eb_initialize_searches(book);
subbook->multi_count = 0;
2021-01-09 22:39:52 +00:00
2021-01-09 23:22:43 +00:00
eb_initialize_fonts(book);
subbook->narrow_current = NULL;
subbook->wide_current = NULL;
2021-01-09 22:39:52 +00:00
}
book->subbook_current = saved_subbook_current;
LOG(("out: eb_initialize_subbooks()"));
}
/*
* Finalize all subbooks in `book'.
*/
void
eb_finalize_subbooks(EB_Book *book)
{
EB_Subbook *subbook;
EB_Subbook *saved_subbook_current;
int i;
LOG(("in: eb_finalize_subbooks(book=%d)", (int)book->code));
saved_subbook_current = book->subbook_current;
for (i = 0, subbook = book->subbooks; i < book->subbook_count;
2021-01-09 23:22:43 +00:00
i++, subbook++) {
book->subbook_current = subbook;
2021-01-09 22:39:52 +00:00
zio_finalize(&subbook->text_zio);
zio_finalize(&subbook->graphic_zio);
zio_finalize(&subbook->sound_zio);
zio_finalize(&subbook->movie_zio);
2021-01-09 23:22:43 +00:00
eb_finalize_searches(book);
eb_finalize_fonts(book);
2021-01-09 22:39:52 +00:00
2021-01-09 23:22:43 +00:00
subbook->narrow_current = NULL;
subbook->wide_current = NULL;
2021-01-09 22:39:52 +00:00
}
book->subbook_current = saved_subbook_current;
LOG(("out: eb_finalize_subbooks()"));
}
/*
* Get information about the current subbook.
*/
static EB_Error_Code
eb_load_subbook(EB_Book *book)
{
EB_Error_Code error_code;
EB_Subbook *subbook;
LOG(("in: eb_load_subbook(book=%d)", (int)book->code));
subbook = book->subbook_current;
/*
* Current subbook must have been set.
*/
if (subbook == NULL) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
2021-01-09 22:39:52 +00:00
}
/*
* Reset contexts.
*/
eb_reset_search_contexts(book);
eb_reset_text_context(book);
eb_reset_binary_context(book);
/*
* If the subbook has already initialized, return immediately.
*/
if (subbook->initialized)
2021-01-09 23:22:43 +00:00
goto succeeded;
2021-01-09 22:39:52 +00:00
if (0 <= zio_file(&subbook->text_zio)) {
2021-01-09 23:22:43 +00:00
/*
* Read index information.
*/
error_code = eb_load_subbook_indexes(book);
if (error_code != EB_SUCCESS)
goto failed;
/*
* Read mutli search information.
*/
error_code = eb_load_multi_searches(book);
if (error_code != EB_SUCCESS)
goto failed;
error_code = eb_load_multi_titles(book);
if (error_code != EB_SUCCESS)
goto failed;
/*
* Rewind the file descriptor of the start file.
*/
if (zio_lseek(&subbook->text_zio,
((off_t) subbook->index_page - 1) * EB_SIZE_PAGE, SEEK_SET) < 0) {
error_code = EB_ERR_FAIL_SEEK_TEXT;
goto failed;
}
2021-01-09 22:39:52 +00:00
}
succeeded:
LOG(("out: eb_load_subbook() = %s", eb_error_string(EB_SUCCESS)));
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_load_subbook() = %s", eb_error_string(error_code)));
return error_code;
}
/*
* Get information about all subbooks in the book.
*/
EB_Error_Code
eb_load_all_subbooks(EB_Book *book)
{
EB_Error_Code error_code;
EB_Subbook *subbook;
int i;
LOG(("in: eb_load_all_subbooks(book=%d)", (int)book->code));
/*
* The book must have been bound.
*/
if (book->path == NULL) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_UNBOUND_BOOK;
goto failed;
2021-01-09 22:39:52 +00:00
}
/*
* Initialize each subbook.
*/
for (i = 0, subbook = book->subbooks; i < book->subbook_count;
2021-01-09 23:22:43 +00:00
i++, subbook++) {
error_code = eb_set_subbook(book, subbook->code);
if (error_code != EB_SUCCESS)
goto failed;
2021-01-09 22:39:52 +00:00
}
eb_unset_subbook(book);
LOG(("out: eb_load_all_subbooks() = %s", eb_error_string(EB_SUCCESS)));
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
eb_unset_subbook(book);
LOG(("out: eb_load_all_subbooks() = %s", eb_error_string(error_code)));
return error_code;
}
/*
* Get index information in the current subbook.
*
* If succeeds, the number of indexes is returned.
* Otherwise, -1 is returned.
*/
static EB_Error_Code
eb_load_subbook_indexes(EB_Book *book)
{
EB_Error_Code error_code;
EB_Subbook *subbook;
EB_Search search;
char buffer[EB_SIZE_PAGE];
char *buffer_p;
int index_count;
int availability;
int global_availability;
EB_Search sebxa_zip_index;
EB_Search sebxa_zip_text;
int i;
LOG(("in: eb_load_subbook_indexes(book=%d)", (int)book->code));
eb_initialize_search(&sebxa_zip_index);
eb_initialize_search(&sebxa_zip_text);
subbook = book->subbook_current;
/*
* Read the index table in the subbook.
*/
if (zio_lseek(&subbook->text_zio,
2021-01-09 23:22:43 +00:00
((off_t) subbook->index_page - 1) * EB_SIZE_PAGE, SEEK_SET) < 0) {
error_code = EB_ERR_FAIL_SEEK_TEXT;
goto failed;
2021-01-09 22:39:52 +00:00
}
if (zio_read(&subbook->text_zio, buffer, EB_SIZE_PAGE) != EB_SIZE_PAGE) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_FAIL_READ_TEXT;
goto failed;
2021-01-09 22:39:52 +00:00
}
/*
* Get start page numbers of the indexes in the subbook.
*/
index_count = eb_uint1(buffer + 1);
if (EB_SIZE_PAGE / 16 - 1 <= index_count) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_UNEXP_TEXT;
goto failed;
2021-01-09 22:39:52 +00:00
}
/*
* Get availavility flag of the index information.
*/
global_availability = eb_uint1(buffer + 4);
if (0x02 < global_availability)
2021-01-09 23:22:43 +00:00
global_availability = 0;
2021-01-09 22:39:52 +00:00
/*
* Set each search method information.
*/
for (i = 0, buffer_p = buffer + 16; i < index_count; i++, buffer_p += 16) {
2021-01-09 23:22:43 +00:00
/*
* Set index style.
*/
eb_initialize_search(&search);
search.index_id = eb_uint1(buffer_p);
search.start_page = eb_uint4(buffer_p + 2);
search.end_page = search.start_page + eb_uint4(buffer_p + 6) - 1;
/*
* Set canonicalization flags.
*/
availability = eb_uint1(buffer_p + 10);
if ((global_availability == 0x00 && availability == 0x02)
|| global_availability == 0x02) {
unsigned int flags;
flags = eb_uint3(buffer_p + 11);
search.katakana = (flags & 0xc00000) >> 22;
search.lower = (flags & 0x300000) >> 20;
if ((flags & 0x0c0000) >> 18 == 0)
search.mark = EB_INDEX_STYLE_DELETE;
else
search.mark = EB_INDEX_STYLE_ASIS;
search.long_vowel = (flags & 0x030000) >> 16;
search.double_consonant = (flags & 0x00c000) >> 14;
search.contracted_sound = (flags & 0x003000) >> 12;
search.small_vowel = (flags & 0x000c00) >> 10;
search.voiced_consonant = (flags & 0x000300) >> 8;
search.p_sound = (flags & 0x0000c0) >> 6;
} else if (search.index_id == 0x70 || search.index_id == 0x90) {
search.katakana = EB_INDEX_STYLE_CONVERT;
search.lower = EB_INDEX_STYLE_CONVERT;
search.mark = EB_INDEX_STYLE_DELETE;
search.long_vowel = EB_INDEX_STYLE_CONVERT;
search.double_consonant = EB_INDEX_STYLE_CONVERT;
search.contracted_sound = EB_INDEX_STYLE_CONVERT;
search.small_vowel = EB_INDEX_STYLE_CONVERT;
search.voiced_consonant = EB_INDEX_STYLE_CONVERT;
search.p_sound = EB_INDEX_STYLE_CONVERT;
} else {
search.katakana = EB_INDEX_STYLE_ASIS;
search.lower = EB_INDEX_STYLE_CONVERT;
search.mark = EB_INDEX_STYLE_ASIS;
search.long_vowel = EB_INDEX_STYLE_ASIS;
search.double_consonant = EB_INDEX_STYLE_ASIS;
search.contracted_sound = EB_INDEX_STYLE_ASIS;
search.small_vowel = EB_INDEX_STYLE_ASIS;
search.voiced_consonant = EB_INDEX_STYLE_ASIS;
search.p_sound = EB_INDEX_STYLE_ASIS;
}
if (book->character_code == EB_CHARCODE_ISO8859_1
|| search.index_id == 0x72
|| search.index_id == 0x92) {
search.space = EB_INDEX_STYLE_ASIS;
} else {
2021-01-09 22:39:52 +00:00
search.space = EB_INDEX_STYLE_DELETE;
2021-01-09 23:22:43 +00:00
}
/*
* Identify search method.
*/
switch (search.index_id) {
case 0x00:
memcpy(&subbook->text, &search, sizeof(EB_Search));
break;
case 0x01:
memcpy(&subbook->menu, &search, sizeof(EB_Search));
break;
case 0x02:
memcpy(&subbook->copyright, &search, sizeof(EB_Search));
break;
case 0x10:
memcpy(&subbook->image_menu, &search, sizeof(EB_Search));
break;
case 0x16:
if (book->disc_code == EB_DISC_EPWING)
subbook->search_title_page = search.start_page;
break;
case 0x21:
if (book->disc_code == EB_DISC_EB
&& zio_mode(&subbook->text_zio) == ZIO_PLAIN)
memcpy(&sebxa_zip_text, &search, sizeof(EB_Search));
break;
case 0x22:
if (book->disc_code == EB_DISC_EB
&& zio_mode(&subbook->text_zio) == ZIO_PLAIN)
memcpy(&sebxa_zip_index, &search, sizeof(EB_Search));
break;
case 0x70:
memcpy(&subbook->endword_kana, &search, sizeof(EB_Search));
break;
case 0x71:
memcpy(&subbook->endword_asis, &search, sizeof(EB_Search));
break;
case 0x72:
memcpy(&subbook->endword_alphabet, &search, sizeof(EB_Search));
break;
case 0x80:
memcpy(&subbook->keyword, &search, sizeof(EB_Search));
break;
case 0x81:
memcpy(&subbook->cross, &search, sizeof(EB_Search));
break;
case 0x90:
memcpy(&subbook->word_kana, &search, sizeof(EB_Search));
break;
case 0x91:
memcpy(&subbook->word_asis, &search, sizeof(EB_Search));
break;
case 0x92:
memcpy(&subbook->word_alphabet, &search, sizeof(EB_Search));
break;
case 0xd8:
memcpy(&subbook->sound, &search, sizeof(EB_Search));
break;
case 0xf1:
if (book->disc_code == EB_DISC_EB) {
subbook->wide_fonts[EB_FONT_16].page = search.start_page;
subbook->wide_fonts[EB_FONT_16].font_code = EB_FONT_16;
}
break;
case 0xf2:
if (book->disc_code == EB_DISC_EB) {
subbook->narrow_fonts[EB_FONT_16].page = search.start_page;
subbook->narrow_fonts[EB_FONT_16].font_code = EB_FONT_16;
}
break;
case 0xf3:
if (book->disc_code == EB_DISC_EB) {
subbook->wide_fonts[EB_FONT_24].page = search.start_page;
subbook->wide_fonts[EB_FONT_24].font_code = EB_FONT_24;
}
break;
case 0xf4:
if (book->disc_code == EB_DISC_EB) {
subbook->narrow_fonts[EB_FONT_24].page = search.start_page;
subbook->narrow_fonts[EB_FONT_24].font_code = EB_FONT_24;
}
break;
case 0xf5:
if (book->disc_code == EB_DISC_EB) {
subbook->wide_fonts[EB_FONT_30].page = search.start_page;
subbook->wide_fonts[EB_FONT_30].font_code = EB_FONT_30;
}
break;
case 0xf6:
if (book->disc_code == EB_DISC_EB) {
subbook->narrow_fonts[EB_FONT_30].page = search.start_page;
subbook->narrow_fonts[EB_FONT_30].font_code = EB_FONT_30;
}
break;
case 0xf7:
if (book->disc_code == EB_DISC_EB) {
subbook->wide_fonts[EB_FONT_48].page = search.start_page;
subbook->wide_fonts[EB_FONT_48].font_code = EB_FONT_48;
}
break;
case 0xf8:
if (book->disc_code == EB_DISC_EB) {
subbook->narrow_fonts[EB_FONT_48].page = search.start_page;
subbook->narrow_fonts[EB_FONT_48].font_code = EB_FONT_48;
}
break;
case 0xff:
if (subbook->multi_count < EB_MAX_MULTI_SEARCHES) {
memcpy(&subbook->multis[subbook->multi_count].search, &search,
sizeof(EB_Search));
subbook->multi_count++;
}
break;
}
eb_finalize_search(&sebxa_zip_text);
2021-01-09 22:39:52 +00:00
}
/*
* Set S-EBXA compression flag.
*/
if (book->disc_code == EB_DISC_EB
2021-01-09 23:22:43 +00:00
&& zio_mode(&subbook->text_zio) == ZIO_PLAIN
&& subbook->text.start_page != 0
&& sebxa_zip_index.start_page != 0
&& sebxa_zip_text.start_page != 0) {
zio_set_sebxa_mode(&subbook->text_zio,
(sebxa_zip_index.start_page - 1) * EB_SIZE_PAGE,
(sebxa_zip_text.start_page - 1) * EB_SIZE_PAGE,
(subbook->text.start_page - 1) * EB_SIZE_PAGE,
subbook->text.end_page * EB_SIZE_PAGE - 1);
2021-01-09 22:39:52 +00:00
}
eb_finalize_search(&sebxa_zip_index);
eb_finalize_search(&sebxa_zip_text);
LOG(("out: eb_load_subbook_indexes() = %s", eb_error_string(EB_SUCCESS)));
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
eb_finalize_search(&sebxa_zip_index);
eb_finalize_search(&sebxa_zip_text);
LOG(("out: eb_load_subbook_indexes() = %s", eb_error_string(error_code)));
return error_code;
}
/*
* Make a subbook list in the book.
*/
EB_Error_Code
eb_subbook_list(EB_Book *book, EB_Subbook_Code *subbook_list,
int *subbook_count)
{
EB_Error_Code error_code;
EB_Subbook_Code *list_p;
int i;
LOG(("in: eb_subbook_list(book=%d)", (int)book->code));
/*
* The book must have been bound.
*/
if (book->path == NULL) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_UNBOUND_BOOK;
goto failed;
2021-01-09 22:39:52 +00:00
}
for (i = 0, list_p = subbook_list; i < book->subbook_count; i++, list_p++)
2021-01-09 23:22:43 +00:00
*list_p = i;
2021-01-09 22:39:52 +00:00
*subbook_count = book->subbook_count;
LOG(("out: eb_subbook_list(subbook_count=%d) = %s", *subbook_count,
2021-01-09 23:22:43 +00:00
eb_error_string(EB_SUCCESS)));
2021-01-09 22:39:52 +00:00
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*subbook_count = 0;
LOG(("out: eb_subbook_list() = %s", eb_error_string(error_code)));
return error_code;
}
/*
* Return a subbook-code of the current subbook.
*/
EB_Error_Code
eb_subbook(EB_Book *book, EB_Subbook_Code *subbook_code)
{
EB_Error_Code error_code;
LOG(("in: eb_subbook(book=%d)", (int)book->code));
/*
* The current subbook must have been set.
*/
if (book->subbook_current == NULL) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
2021-01-09 22:39:52 +00:00
}
*subbook_code = book->subbook_current->code;
LOG(("out: eb_subbook(subbook_code=%d) = %s", *subbook_code,
2021-01-09 23:22:43 +00:00
eb_error_string(EB_SUCCESS)));
2021-01-09 22:39:52 +00:00
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*subbook_code = EB_SUBBOOK_INVALID;
LOG(("out: eb_subbook() = %s", eb_error_string(error_code)));
return error_code;
}
/*
* Return a title of the current subbook.
*/
EB_Error_Code
eb_subbook_title(EB_Book *book, char *title)
{
EB_Error_Code error_code;
LOG(("in: eb_subbook_title(book=%d)", (int)book->code));
/*
* The current subbook must have been set.
*/
if (book->subbook_current == NULL) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
2021-01-09 22:39:52 +00:00
}
strcpy(title, book->subbook_current->title);
LOG(("out: eb_subbook_title(title=%s) = %s", title,
2021-01-09 23:22:43 +00:00
eb_error_string(EB_SUCCESS)));
2021-01-09 22:39:52 +00:00
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*title = '\0';
LOG(("out: eb_subbook_title() = %s", eb_error_string(error_code)));
return error_code;
}
/*
* Return a title of the specified subbook `subbook_code'.
*/
EB_Error_Code
eb_subbook_title2(EB_Book *book, EB_Subbook_Code subbook_code, char *title)
{
EB_Error_Code error_code;
LOG(("in: eb_subbook_title2(book=%d, subbook_code=%d)",
2021-01-09 23:22:43 +00:00
(int)book->code, (int)subbook_code));
2021-01-09 22:39:52 +00:00
/*
* The book must have been bound.
*/
if (book->path == NULL) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_UNBOUND_BOOK;
goto failed;
2021-01-09 22:39:52 +00:00
}
/*
* Check for the subbook-code.
*/
if (subbook_code < 0 || book->subbook_count <= subbook_code) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_NO_SUCH_SUB;
goto failed;
2021-01-09 22:39:52 +00:00
}
strcpy(title, (book->subbooks + subbook_code)->title);
LOG(("out: eb_subbook_title2(title=%s) = %s", title,
2021-01-09 23:22:43 +00:00
eb_error_string(EB_SUCCESS)));
2021-01-09 22:39:52 +00:00
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*title = '\0';
LOG(("out: eb_subbook_title2() = %s", eb_error_string(error_code)));
return error_code;
}
/*
* Return a directory name of the current subbook.
*/
EB_Error_Code
eb_subbook_directory(EB_Book *book, char *directory)
{
EB_Error_Code error_code;
char *p;
LOG(("in: eb_subbook_directory(book=%d)", (int)book->code));
/*
* Current subbook must have been set.
*/
if (book->subbook_current == NULL) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_NO_CUR_SUB;
goto failed;
2021-01-09 22:39:52 +00:00
}
/*
* Copy directory name.
* Upper letters are converted to lower letters.
*/
strcpy(directory, book->subbook_current->directory_name);
for (p = directory; *p != '\0'; p++) {
2021-01-09 23:22:43 +00:00
if ('A' <= *p && *p <= 'Z')
*p = ASCII_TOLOWER(*p);
2021-01-09 22:39:52 +00:00
}
LOG(("out: eb_subbook_directory(directory=%s) = %s", directory,
2021-01-09 23:22:43 +00:00
eb_error_string(EB_SUCCESS)));
2021-01-09 22:39:52 +00:00
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*directory = '\0';
LOG(("out: eb_subbook_directory() = %s", eb_error_string(error_code)));
return error_code;
}
/*
* Return a directory name of the specified subbook `subbook_code'.
*/
EB_Error_Code
eb_subbook_directory2(EB_Book *book, EB_Subbook_Code subbook_code,
char *directory)
{
EB_Error_Code error_code;
char *p;
LOG(("in: eb_subbook_directory2(book=%d, subbook_code=%d)",
2021-01-09 23:22:43 +00:00
(int)book->code, (int)subbook_code));
2021-01-09 22:39:52 +00:00
/*
* The book must have been bound.
*/
if (book->path == NULL) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_UNBOUND_BOOK;
goto failed;
2021-01-09 22:39:52 +00:00
}
/*
* Check for the subbook-code.
*/
if (subbook_code < 0 || book->subbook_count <= subbook_code) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_NO_SUCH_SUB;
goto failed;
2021-01-09 22:39:52 +00:00
}
/*
* Copy directory name.
* Upper letters are converted to lower letters.
*/
strcpy(directory, (book->subbooks + subbook_code)->directory_name);
for (p = directory; *p != '\0'; p++) {
2021-01-09 23:22:43 +00:00
if ('A' <= *p && *p <= 'Z')
*p = ASCII_TOLOWER(*p);
2021-01-09 22:39:52 +00:00
}
LOG(("out: eb_subbook_directory2(directory=%s) = %s", directory,
2021-01-09 23:22:43 +00:00
eb_error_string(EB_SUCCESS)));
2021-01-09 22:39:52 +00:00
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
*directory = '\0';
LOG(("out: eb_subbook_directory2() = %s", eb_error_string(error_code)));
return error_code;
}
/*
* Set the subbook `subbook_code' as the current subbook.
*/
EB_Error_Code
eb_set_subbook(EB_Book *book, EB_Subbook_Code subbook_code)
{
EB_Error_Code error_code = EB_SUCCESS;
LOG(("in: eb_set_subbook(book=%d, subbook_code=%d)",
2021-01-09 23:22:43 +00:00
(int)book->code, (int)subbook_code));
2021-01-09 22:39:52 +00:00
/*
* The book must have been bound.
*/
if (book->path == NULL) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_UNBOUND_BOOK;
goto failed;
2021-01-09 22:39:52 +00:00
}
/*
* Check for the subbook-code.
*/
if (subbook_code < 0 || book->subbook_count <= subbook_code) {
2021-01-09 23:22:43 +00:00
error_code = EB_ERR_NO_SUCH_SUB;
goto failed;
2021-01-09 22:39:52 +00:00
}
/*
* If the subbook has already been set as the current subbook,
* there is nothing to be done.
* Otherwise close the previous subbook.
*/
if (book->subbook_current != NULL) {
2021-01-09 23:22:43 +00:00
if (book->subbook_current->code == subbook_code)
goto succeeded;
eb_unset_subbook(book);
2021-01-09 22:39:52 +00:00
}
/*
* Set the current subbook.
*/
book->subbook_current = book->subbooks + subbook_code;
/*
* Dispatch.
*/
if (book->disc_code == EB_DISC_EB)
2021-01-09 23:22:43 +00:00
error_code = eb_set_subbook_eb(book, subbook_code);
2021-01-09 22:39:52 +00:00
else
2021-01-09 23:22:43 +00:00
error_code = eb_set_subbook_epwing(book, subbook_code);
2021-01-09 22:39:52 +00:00
if (error_code != EB_SUCCESS)
2021-01-09 23:22:43 +00:00
goto failed;
2021-01-09 22:39:52 +00:00
/*
* Load the subbook.
*/
error_code = eb_load_subbook(book);
if (error_code != EB_SUCCESS)
2021-01-09 23:22:43 +00:00
goto failed;
2021-01-09 22:39:52 +00:00
/*
* Load font files.
*/
eb_load_font_headers(book);
succeeded:
book->subbook_current->initialized = 1;
LOG(("out: eb_set_subbook() = %s", eb_error_string(EB_SUCCESS)));
return error_code;
/*
* An error occurs...
*/
failed:
if (book->subbook_current != NULL) {
2021-01-09 23:22:43 +00:00
zio_close(&book->subbook_current->text_zio);
zio_close(&book->subbook_current->graphic_zio);
zio_close(&book->subbook_current->sound_zio);
zio_close(&book->subbook_current->movie_zio);
2021-01-09 22:39:52 +00:00
}
book->subbook_current = NULL;
LOG(("out: eb_set_subbook() = %s", eb_error_string(error_code)));
return error_code;
}
/*
* Set the subbook `subbook_code' as the current subbook.
*/
static EB_Error_Code
eb_set_subbook_eb(EB_Book *book, EB_Subbook_Code subbook_code)
{
EB_Error_Code error_code;
EB_Subbook *subbook;
char text_path_name[EB_MAX_PATH_LENGTH + 1];
char graphic_path_name[EB_MAX_PATH_LENGTH + 1];
Zio_Code text_zio_code;
Zio_Code graphic_zio_code;
LOG(("in: eb_set_subbook_eb(book=%d, subbook_code=%d)",
2021-01-09 23:22:43 +00:00
(int)book->code, (int)subbook_code));
2021-01-09 22:39:52 +00:00
subbook = book->subbook_current;
/*
* Open a text file if exists.
*/
text_zio_code = ZIO_INVALID;
if (subbook->initialized) {
2021-01-09 23:22:43 +00:00
if (zio_mode(&subbook->text_zio) != ZIO_INVALID)
text_zio_code = ZIO_REOPEN;
2021-01-09 22:39:52 +00:00
} else {
2021-01-09 23:22:43 +00:00
eb_canonicalize_file_name(subbook->text_file_name);
if (eb_find_file_name2(book->path, subbook->directory_name,
EB_FILE_NAME_START, subbook->text_file_name) == EB_SUCCESS) {
eb_path_name_zio_code(subbook->text_file_name, ZIO_PLAIN,
&text_zio_code);
}
2021-01-09 22:39:52 +00:00
}
if (text_zio_code != ZIO_INVALID) {
2021-01-09 23:22:43 +00:00
eb_compose_path_name2(book->path, subbook->directory_name,
subbook->text_file_name, text_path_name);
if (zio_open(&subbook->text_zio, text_path_name, text_zio_code) < 0) {
error_code = EB_ERR_FAIL_OPEN_TEXT;
goto failed;
}
text_zio_code = zio_mode(&subbook->text_zio);
2021-01-09 22:39:52 +00:00
}
/*
* Open a graphic file if exists.
*/
graphic_zio_code = ZIO_INVALID;
if (subbook->initialized) {
2021-01-09 23:22:43 +00:00
if (zio_mode(&subbook->graphic_zio) != ZIO_INVALID)
graphic_zio_code = ZIO_REOPEN;
2021-01-09 22:39:52 +00:00
} else if (text_zio_code != ZIO_INVALID) {
2021-01-09 23:22:43 +00:00
strcpy(subbook->graphic_file_name, subbook->text_file_name);
graphic_zio_code = text_zio_code;
2021-01-09 22:39:52 +00:00
}
if (graphic_zio_code != ZIO_INVALID) {
2021-01-09 23:22:43 +00:00
eb_compose_path_name2(book->path, subbook->directory_name,
subbook->graphic_file_name, graphic_path_name);
if (zio_open(&subbook->graphic_zio, graphic_path_name,
graphic_zio_code) < 0) {
error_code = EB_ERR_FAIL_OPEN_BINARY;
goto failed;
}
graphic_zio_code = zio_mode(&subbook->graphic_zio);
2021-01-09 22:39:52 +00:00
}
LOG(("out: eb_set_subbook_eb() = %s", eb_error_string(EB_SUCCESS)));
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_set_subbook_eb() = %s", eb_error_string(error_code)));
return error_code;
}
/*
* Set the subbook `subbook_code' as the current subbook.
*/
static EB_Error_Code
eb_set_subbook_epwing(EB_Book *book, EB_Subbook_Code subbook_code)
{
EB_Error_Code error_code;
EB_Subbook *subbook;
char text_path_name[EB_MAX_PATH_LENGTH + 1];
char graphic_path_name[EB_MAX_PATH_LENGTH + 1];
char sound_path_name[EB_MAX_PATH_LENGTH + 1];
Zio_Code text_zio_code;
Zio_Code graphic_zio_code;
Zio_Code sound_zio_code;
LOG(("in: eb_set_subbook_epwing(book=%d, subbook_code=%d)",
2021-01-09 23:22:43 +00:00
(int)book->code, (int)subbook_code));
2021-01-09 22:39:52 +00:00
subbook = book->subbook_current;
if (!subbook->initialized) {
2021-01-09 23:22:43 +00:00
/*
* Adjust directory names.
*/
strcpy(subbook->data_directory_name, EB_DIRECTORY_NAME_DATA);
eb_fix_directory_name2(book->path, subbook->directory_name,
subbook->data_directory_name);
strcpy(subbook->gaiji_directory_name, EB_DIRECTORY_NAME_GAIJI);
eb_fix_directory_name2(book->path, subbook->directory_name,
subbook->gaiji_directory_name);
strcpy(subbook->movie_directory_name, EB_DIRECTORY_NAME_MOVIE);
eb_fix_directory_name2(book->path, subbook->directory_name,
subbook->movie_directory_name);
2021-01-09 22:39:52 +00:00
}
/*
* Open a text file if exists.
*
* If a subbook has stream data only, its index_page has been set
* to 0. In this case, we must not try to open a text file of
* the subbook, since the text file may be for another subbook.
* Remember that subbooks can share a `data' sub-directory.
*/
text_zio_code = ZIO_INVALID;
if (subbook->initialized) {
2021-01-09 23:22:43 +00:00
if (zio_mode(&subbook->text_zio) != ZIO_INVALID)
text_zio_code = ZIO_REOPEN;
2021-01-09 22:39:52 +00:00
} else if (subbook->index_page > 0) {
2021-01-09 23:22:43 +00:00
eb_canonicalize_file_name(subbook->text_file_name);
if (eb_find_file_name3(book->path, subbook->directory_name,
subbook->data_directory_name, subbook->text_file_name,
subbook->text_file_name) == EB_SUCCESS) {
eb_path_name_zio_code(subbook->text_file_name,
subbook->text_hint_zio_code, &text_zio_code);
}
2021-01-09 22:39:52 +00:00
}
if (text_zio_code != ZIO_INVALID) {
2021-01-09 23:22:43 +00:00
eb_compose_path_name3(book->path, subbook->directory_name,
subbook->data_directory_name, subbook->text_file_name,
text_path_name);
if (zio_open(&subbook->text_zio, text_path_name, text_zio_code) < 0) {
subbook = NULL;
error_code = EB_ERR_FAIL_OPEN_TEXT;
goto failed;
}
text_zio_code = zio_mode(&subbook->text_zio);
2021-01-09 22:39:52 +00:00
}
/*
* Open a graphic file if exists.
*/
graphic_zio_code = ZIO_INVALID;
if (subbook->initialized) {
2021-01-09 23:22:43 +00:00
if (zio_mode(&subbook->graphic_zio) != ZIO_INVALID)
graphic_zio_code = ZIO_REOPEN;
2021-01-09 22:39:52 +00:00
} else if (text_zio_code != ZIO_INVALID) {
2021-01-09 23:22:43 +00:00
eb_canonicalize_file_name(subbook->graphic_file_name);
if (eb_find_file_name3(book->path, subbook->directory_name,
subbook->data_directory_name, subbook->graphic_file_name,
subbook->graphic_file_name) == EB_SUCCESS) {
eb_path_name_zio_code(subbook->graphic_file_name,
subbook->graphic_hint_zio_code, &graphic_zio_code);
}
2021-01-09 22:39:52 +00:00
}
if (graphic_zio_code != ZIO_INVALID) {
2021-01-09 23:22:43 +00:00
eb_compose_path_name3(book->path, subbook->directory_name,
subbook->data_directory_name, subbook->graphic_file_name,
graphic_path_name);
if (zio_open(&subbook->graphic_zio, graphic_path_name,
graphic_zio_code) < 0) {
error_code = EB_ERR_FAIL_OPEN_BINARY;
goto failed;
}
graphic_zio_code = zio_mode(&subbook->graphic_zio);
2021-01-09 22:39:52 +00:00
}
/*
* Open a sound file if exists.
*/
sound_zio_code = ZIO_INVALID;
if (subbook->initialized) {
2021-01-09 23:22:43 +00:00
if (zio_mode(&subbook->sound_zio) != ZIO_INVALID)
sound_zio_code = ZIO_REOPEN;
2021-01-09 22:39:52 +00:00
} else if (text_zio_code != ZIO_INVALID) {
2021-01-09 23:22:43 +00:00
eb_canonicalize_file_name(subbook->sound_file_name);
if (eb_find_file_name3(book->path, subbook->directory_name,
subbook->data_directory_name, subbook->sound_file_name,
subbook->sound_file_name) == EB_SUCCESS) {
eb_path_name_zio_code(subbook->sound_file_name,
subbook->sound_hint_zio_code, &sound_zio_code);
}
2021-01-09 22:39:52 +00:00
}
if (sound_zio_code != ZIO_INVALID) {
2021-01-09 23:22:43 +00:00
eb_compose_path_name3(book->path, subbook->directory_name,
subbook->data_directory_name, subbook->sound_file_name,
sound_path_name);
if (zio_open(&subbook->sound_zio, sound_path_name,
sound_zio_code) < 0) {
error_code = EB_ERR_FAIL_OPEN_BINARY;
goto failed;
}
sound_zio_code = zio_mode(&subbook->sound_zio);
2021-01-09 22:39:52 +00:00
}
LOG(("out: eb_set_subbook_epwing() = %s", eb_error_string(EB_SUCCESS)));
return EB_SUCCESS;
/*
* An error occurs...
*/
failed:
LOG(("out: eb_set_subbook_epwing() = %s", eb_error_string(error_code)));
return error_code;
}
/*
* Unset the current subbook.
*/
void
eb_unset_subbook(EB_Book *book)
{
LOG(("in: eb_unset_subbook(book=%d)", (int)book->code));
/*
* Close the file of the current subbook.
*/
if (book->subbook_current != NULL) {
2021-01-09 23:22:43 +00:00
eb_unset_font(book);
eb_unset_binary(book);
zio_close(&book->subbook_current->text_zio);
zio_close(&book->subbook_current->graphic_zio);
zio_close(&book->subbook_current->sound_zio);
zio_close(&book->subbook_current->movie_zio);
book->subbook_current = NULL;
2021-01-09 22:39:52 +00:00
}
LOG(("out: eb_unset_subbook()"));
}