Last active
November 1, 2025 07:03
-
-
Save zakki/36ce9d822f7ee7af1924ceebeb9f7830 to your computer and use it in GitHub Desktop.
Fix HSP 3.7 file I/O
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| diff --git i/hspproj/hsp3/filepack.cpp w/hspproj/hsp3/filepack.cpp | |
| index c03bc83..1f4beba 100644 | |
| --- i/hspproj/hsp3/filepack.cpp | |
| +++ w/hspproj/hsp3/filepack.cpp | |
| @@ -244,22 +244,24 @@ int FilePack::pack_fgetc(FILE* ptr) | |
| int FilePack::pack_flength(char* name) | |
| { | |
| + HFPOBJ* obj; | |
| + obj = SearchFileObject(name); | |
| + if (obj) return (int)obj->size; | |
| - HFPOBJ* obj; | |
| - obj = SearchFileObject(name); | |
| - if (obj) return (int)obj->size; | |
| + int size = hsp3_flength(name); | |
| + if (size>=0) return size; | |
| - int size = hsp3_flength(name); | |
| - if (size>=0) return size; | |
| - | |
| - FILE* ff = pack_fopen(name); | |
| - if (ff != NULL) { | |
| - if (memfile_active) { // メモリストリーム時 | |
| - return memfile.size; | |
| - } | |
| - pack_fclose(ff); | |
| - } | |
| - return -1; | |
| + FILE* ff = pack_fopen(name); | |
| + if (ff != NULL) { | |
| + if (memfile_active) { // メモリストリーム時 | |
| + return memfile.size; | |
| + } | |
| + fseek(ff, 0, SEEK_END); | |
| + size = (int)ftell(ff); | |
| + pack_fclose(ff); | |
| + return size; | |
| + } | |
| + return -1; | |
| } | |
| diff --git i/hspproj/hsp3/hsp3utfcnv.cpp w/hspproj/hsp3/hsp3utfcnv.cpp | |
| index 023102b..d62dcbc 100644 | |
| --- i/hspproj/hsp3/hsp3utfcnv.cpp | |
| +++ w/hspproj/hsp3/hsp3utfcnv.cpp | |
| @@ -264,6 +264,14 @@ FILE *hsp3_fopen(char*name, int offset) | |
| } | |
| #endif | |
| +#ifdef HSPIOS | |
| + { | |
| + char* path = gb_filepath(name); | |
| + printf("Load %s", path); | |
| + hsp3_fp = fopen(path, "rb"); | |
| + return hsp3_fp; | |
| + } | |
| +#endif | |
| // Linux | |
| hsp3_fp = fopen(name, "rb"); | |
| #ifdef HSPDEBUG | |
| @@ -350,10 +358,11 @@ void hsp3_fclose(FILE* ptr) | |
| int hsp3_flength(char* name) | |
| { | |
| #ifdef HSPIOS | |
| - { | |
| - int length = gb_existdata( name ); | |
| - return length; | |
| - } | |
| + { | |
| + int length = gb_existdata( name ); | |
| + if (length >= 0) | |
| + return length; | |
| + } | |
| #endif | |
| #ifdef HSPNDK |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // File Pack manager 2 | |
| // Copyright 2022- ONION software/onitama | |
| // | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <cctype> | |
| #ifdef HSPWIN | |
| #include <direct.h> | |
| #include "windows.h" | |
| #endif | |
| #if defined(HSPLINUX) || defined(HSPNDK) || defined(HSPIOS) | |
| #include<unistd.h> | |
| #define _getcwd getcwd | |
| #endif | |
| #include "hsp3config.h" | |
| #include "supio.h" | |
| #include "filepack.h" | |
| #include "hsp3crypt.h" | |
| #define _MALLOC malloc | |
| #define _FREE free | |
| #define WELCOMEMSG "DPM2 Manager 1.0" | |
| #define DPMFILEEXT ".dpm" | |
| #define DPMENCODE_DEFVAL 0 | |
| /*------------------------------------------------------------*/ | |
| /* | |
| UTF8 Util | |
| */ | |
| /*------------------------------------------------------------*/ | |
| void FilePack::StrCase(char* str) | |
| { | |
| // strをすべて小文字に(utf8/sjis対応版) | |
| // ('\'を'/'にも変換) | |
| // | |
| unsigned char* p; | |
| unsigned char a1; | |
| p = (unsigned char*)str; | |
| while (1) { | |
| a1 = *p; if (a1 == 0) break; | |
| if (a1 == '\\') a1 = '/'; | |
| *p = tolower(a1); | |
| p+=StrCopyLetter((char *)p,NULL); // 検索位置を移動 | |
| } | |
| } | |
| void FilePack::StrSplit(char *target, char *fpath, char *filename) | |
| { | |
| // targetをパスとファイル名に分離(utf8/sjis対応版) | |
| // | |
| unsigned char *p; | |
| unsigned char *div; | |
| unsigned char a1; | |
| unsigned char *dst; | |
| int i; | |
| int diff; | |
| fpath[0] = 0; | |
| filename[0] = 0; | |
| p = (unsigned char*)target; | |
| div = p; | |
| while (1) { | |
| a1 = *p; if (a1 == 0) break; | |
| if (a1 == '\\') { | |
| div = p; | |
| } | |
| if (a1 == '/') { | |
| div = p; | |
| } | |
| p += StrCopyLetter((char*)p, NULL); // 検索位置を移動 | |
| } | |
| i = 0; | |
| p = (unsigned char*)target; | |
| if (div != p) { | |
| dst = (unsigned char*)fpath; | |
| while (1) { | |
| if (p>div) break; | |
| a1 = *p; if (a1 == 0) break; | |
| diff = StrCopyLetter((char*)p, (char *)dst); // 1文字コピー | |
| p += diff; // 検索位置を移動 | |
| dst += diff; // 検索位置を移動 | |
| i++; | |
| if ( i>= HFP_NAME_MAX ) break; | |
| } | |
| *dst++ = 0; | |
| } | |
| i = 0; | |
| dst = (unsigned char*)filename; | |
| while (1) { | |
| a1 = *p; if (a1 == 0) break; | |
| diff = StrCopyLetter((char*)p, (char*)dst); // 1文字コピー | |
| p += diff; // 検索位置を移動 | |
| dst += diff; // 検索位置を移動 | |
| i++; | |
| if (i >= HFP_NAME_MAX) break; | |
| } | |
| *dst++ = 0; | |
| } | |
| /*------------------------------------------------------------*/ | |
| /* | |
| constructor | |
| */ | |
| /*------------------------------------------------------------*/ | |
| FilePack::FilePack() | |
| { | |
| // 初期化 | |
| // | |
| int i; | |
| for(i=0;i<HFP_MAX;i++) { | |
| buf[i] = NULL; | |
| hsp3crypt[i] = NULL; | |
| } | |
| memfile_enable = true; | |
| memfile_active = false; | |
| Reset(); | |
| } | |
| FilePack::~FilePack() | |
| { | |
| // すべて破棄 | |
| // | |
| Reset(); | |
| } | |
| /*------------------------------------------------------------*/ | |
| /* | |
| interface (File Service) | |
| */ | |
| /*------------------------------------------------------------*/ | |
| void FilePack::pack_memenable(bool sw) | |
| { | |
| memfile_enable = sw; | |
| } | |
| FILE* FilePack::pack_fopen(char* name, int offset) | |
| { | |
| HFPHED* hed; | |
| HFPOBJ* obj; | |
| FILE* ff; | |
| int ofs; | |
| int encode; | |
| filebase = HFP_FILEBASE_NORMAL; | |
| encode = 0; | |
| int i; | |
| i = *(int*)name; | |
| memfile_active = false; | |
| fopen_crypt = 0; | |
| if ((i == 0x3a4d454d) || (i == 0x3a6d656d)) { // 'MEM:'をチェックする | |
| if (memfile_enable == false) { | |
| return NULL; | |
| } | |
| if (memfile.pt == NULL) { | |
| return NULL; | |
| } | |
| memfile_active = true; | |
| filebase = HFP_FILEBASE_MEMFILE; | |
| return (FILE *)name; | |
| } | |
| obj = SearchFileObject(name); | |
| if (obj == NULL) { | |
| filebase = HFP_FILEBASE_NORMAL; | |
| return hsp3_fopen(name,offset); | |
| } | |
| if (offset < 0) return NULL; | |
| hed = GetCurrentHeader(); | |
| ofs = hed->filetable + (int)obj->offset; | |
| ofs += offset; | |
| if (curnum == exedpm_slot) { | |
| filebase = HFP_FILEBASE_PACKEXE; | |
| ofs += exedpm_offset; | |
| } | |
| else { | |
| filebase = HFP_FILEBASE_PACKDPM; | |
| } | |
| HSP3Crypt* cm = GetCurrentCryptManager(); | |
| ff = hsp3_fopen(cm->GetBasePath(), ofs); | |
| if (ff == NULL) return NULL; | |
| fopen_crypt = obj->crypt; | |
| if (obj->crypt) { | |
| char pathname[HFP_PATH_MAX + 1]; | |
| strcpy(pathname, GetFolderName(obj)); | |
| strcat(pathname, GetFileName(obj)); | |
| int enc_crypt = cm->GetCRC32(pathname, strlen(pathname)); // ファイルパスを暗号キーにする | |
| enc_crypt = cm->GetSalt(enc_crypt); | |
| if (enc_crypt == 0) enc_crypt = 1; | |
| int size = (int)obj->size; | |
| if (enc_crypt != obj->crypt) { | |
| return NULL; | |
| } | |
| cm->DataSet(NULL, size, obj->crypt); | |
| cm->SetOffset(offset); | |
| } | |
| return ff; | |
| } | |
| int FilePack::GetCurrentDPMOffset(void) | |
| { | |
| if (curnum == exedpm_slot) { | |
| return exedpm_offset; | |
| } | |
| return 0; | |
| } | |
| void FilePack::pack_fclose(FILE* ptr) | |
| { | |
| if (memfile_active) { | |
| memfile.pt = NULL; | |
| memfile_active = false; | |
| return; | |
| } | |
| hsp3_fclose(ptr); | |
| } | |
| int FilePack::pack_fgetc(FILE* ptr) | |
| { | |
| int i = 0; | |
| int res = pack_fread(ptr,&i,1); | |
| if (res <= 0) return -1; | |
| return i; | |
| } | |
| int FilePack::pack_flength(char* name) | |
| { | |
| HFPOBJ* obj; | |
| obj = SearchFileObject(name); | |
| if (obj) return (int)obj->size; | |
| int size = hsp3_flength(name); | |
| if (size>=0) return size; | |
| FILE* ff = pack_fopen(name); | |
| if (ff != NULL) { | |
| if (memfile_active) { // メモリストリーム時 | |
| return memfile.size; | |
| } | |
| fseek(ff, 0, SEEK_END); | |
| size = (int)ftell(ff); | |
| pack_fclose(ff); | |
| return size; | |
| } | |
| return -1; | |
| } | |
| int FilePack::pack_fread(FILE* ptr, void* mem, int size) | |
| { | |
| int len; | |
| if (ptr == NULL) return -1; | |
| if (memfile_active) { | |
| len = size; | |
| if ((memfile.cur + size) >= memfile.size) len = memfile.size - memfile.cur; | |
| if (len > 0) { | |
| memcpy(mem, memfile.pt + memfile.cur, len); | |
| memfile.cur += len; | |
| } | |
| return len; | |
| } | |
| len = (int)hsp3_fread(ptr, mem, size); | |
| if (filebase == HFP_FILEBASE_NORMAL) { | |
| return len; | |
| } | |
| if (fopen_crypt) { | |
| int i; | |
| unsigned char* p = (unsigned char*)mem; | |
| HSP3Crypt* cm = GetCurrentCryptManager(); | |
| for (i = 0; i < len; i++) { | |
| *p = cm->Decrypt(*p); | |
| p++; | |
| } | |
| } | |
| return len; | |
| } | |
| int FilePack::pack_fbase(char* name) | |
| { | |
| FILE* ff = pack_fopen(name); | |
| if (ff == NULL) return -1; | |
| pack_fclose(ff); | |
| return filebase; | |
| } | |
| void FilePack::pack_memfile(void* mem, int size) | |
| { | |
| memfile.pt = (char*)mem; | |
| memfile.cur = 0; | |
| memfile.size = size; | |
| } | |
| void FilePack::pack_getinfstr(char* inf) | |
| { | |
| HFPHED* hed = GetPackHeader(0); | |
| if (hed == NULL) { | |
| *inf = 0; | |
| return; | |
| } | |
| int ofs = 0; | |
| HSP3Crypt* cm = hsp3crypt[0]; | |
| if (exedpm_slot == 0) { | |
| ofs = exedpm_offset; | |
| } | |
| sprintf(inf, "%s,%d", cm->GetBasePath(), ofs ); | |
| } | |
| /*------------------------------------------------------------*/ | |
| /* | |
| interface (read) | |
| */ | |
| /*------------------------------------------------------------*/ | |
| void FilePack::Reset( void ) | |
| { | |
| int i; | |
| for (i = 0; i < HFP_MAX; i++) { | |
| DeleteSlot(i); | |
| } | |
| curnum = 0; | |
| wrtbuf = NULL; | |
| errbuf = NULL; | |
| wrtstr = NULL; | |
| exedpm_slot = -1; | |
| exedpm_offset = 0; | |
| filebase = 0; | |
| } | |
| void FilePack::DeleteSlot(int slot) | |
| { | |
| int i = slot; | |
| if ((i<0)||(i>=HFP_MAX)) { | |
| return; | |
| } | |
| if (buf[i] != NULL) { | |
| _FREE(buf[i]); | |
| buf[i] = NULL; | |
| } | |
| if (hsp3crypt[i] != NULL) { | |
| delete hsp3crypt[i]; | |
| hsp3crypt[i] = NULL; | |
| } | |
| } | |
| int FilePack::GetEmptySlot(void) | |
| { | |
| int i; | |
| for (i = 0; i < HFP_MAX; i++) { | |
| if (buf[i] == NULL) return i; | |
| } | |
| return -1; | |
| } | |
| void FilePack::PrepareRead(int slot, int value) | |
| { | |
| // hsp3cryptを準備する | |
| // | |
| char pwtmp[128]; | |
| sprintf(pwtmp, "HSP3Encode:%d", value); | |
| //Print(pwtmp); | |
| DeleteSlot(slot); | |
| hsp3crypt[slot] = new HSP3Crypt(); | |
| hsp3crypt[slot]->SetPassword(pwtmp); | |
| } | |
| int FilePack::LoadPackFile( char *fname, int encode, int dpmoffset, int slot) | |
| { | |
| FILE *ff; | |
| HFPHED testhed; | |
| HFPHED *p; | |
| int i; | |
| int hedsize; | |
| char dpmname[HFP_PATH_MAX + 1]; | |
| //Print(WELCOMEMSG); | |
| curnum = slot; | |
| if (curnum < 0) { | |
| curnum = GetEmptySlot(); | |
| } | |
| if (curnum < 0) return -1; | |
| *dpmname = 0; | |
| #ifdef HSPWIN | |
| if (dpmoffset == 0) { | |
| bool addcurrent = true; | |
| char a1 = *fname; | |
| // fnameがフルパスの場合はパスを補完しない | |
| if ((a1 == 0x5c) || (a1 == '/')) addcurrent = false; | |
| if ((a1 != 0)&&(fname[1]==':')) addcurrent = false; | |
| if (addcurrent) { | |
| _getcwd(dpmname, HFP_PATH_MAX); | |
| strcat(dpmname, "/"); | |
| } | |
| } | |
| #endif | |
| strcat(dpmname, fname); | |
| //strcat(dpmname, DPMFILEEXT); | |
| dpmname[HFP_PATH_MAX] = 0; | |
| ff = hsp3_fopen(dpmname, dpmoffset); | |
| if (ff==NULL) return -2; | |
| hsp3_fread(ff, &testhed, sizeof(HFPHED)); | |
| hsp3_fclose(ff); | |
| if (dpmoffset > 0) { | |
| exedpm_slot = curnum; | |
| exedpm_offset = dpmoffset; | |
| } | |
| hedsize = testhed.filetable; | |
| if (hedsize < sizeof(HFPHED)) return -2; | |
| p = (HFPHED *)_MALLOC( hedsize ); | |
| ff=hsp3_fopen(dpmname, dpmoffset); | |
| if (ff == NULL) { | |
| _FREE(p); | |
| return -2; | |
| } | |
| hsp3_fread( ff, p, hedsize ); | |
| hsp3_fclose(ff); | |
| if (( p->h1 != HFP_MAGIC1 )||( p->h2 != HFP_MAGIC2 )|| | |
| ( p->h3 != HFP_MAGIC3 )||( p->h4 != HFP_MAGIC4 )) { | |
| _FREE( p ); | |
| return -3; | |
| } | |
| PrepareRead(curnum, p->seed + encode); | |
| buf[curnum] = p; | |
| HSP3Crypt* cm = GetCurrentCryptManager(); | |
| if (encode>0) { | |
| if (p->salt != cm->GetSalt(encode + p->seed)) { | |
| return -4; | |
| } | |
| } | |
| cm->SetBasePath(dpmname); | |
| HFPOBJ* obj; | |
| obj = GetCurrentObjectHeader(); | |
| for (i = 0; i < p->max_file; i++) { | |
| obj->slot = curnum; | |
| obj++; | |
| } | |
| return 0; | |
| } | |
| /*------------------------------------------------------------*/ | |
| /* | |
| interface (info) | |
| */ | |
| /*------------------------------------------------------------*/ | |
| int FilePack::GetPackSlot( void ) | |
| { | |
| return curnum; | |
| } | |
| HFPHED *FilePack::GetPackHeader( int slot ) | |
| { | |
| if (( slot < 0 )||( slot >= HFP_MAX)) return NULL; | |
| return buf[slot]; | |
| } | |
| HFPHED* FilePack::GetCurrentHeader(void) | |
| { | |
| return GetPackHeader(curnum); | |
| } | |
| HFPOBJ* FilePack::GetCurrentObjectHeader(void) | |
| { | |
| HFPHED *hed = GetCurrentHeader(); | |
| HFPOBJ* obj = (HFPOBJ*)(hed + 1); | |
| return obj; | |
| } | |
| HSP3Crypt *FilePack::GetCurrentCryptManager(void) | |
| { | |
| return (hsp3crypt[curnum]); | |
| } | |
| int FilePack::GetFileNum( HFPHED *hed ) | |
| { | |
| return hed->max_file; | |
| } | |
| char *FilePack::GetPackName( HFPHED *hed ) | |
| { | |
| char *strbase; | |
| strbase = ((char *)hed) + hed->strtable; | |
| return strbase + hed->myname; | |
| } | |
| HFPOBJ* FilePack::GetFileObject(HFPHED* hed, int id) | |
| { | |
| HFPOBJ* obj; | |
| if ((id < 0) || (id >= hed->max_file)) return NULL; | |
| obj = (HFPOBJ*)(hed + 1); | |
| return &obj[id]; | |
| } | |
| char* FilePack::GetString(HFPHED* hed, int ptr) | |
| { | |
| HFPHED* p = hed; | |
| if (p == NULL) return NULL; | |
| char* strbase = ((char*)p) + p->strtable; | |
| return strbase + ptr; | |
| } | |
| char* FilePack::GetFileName(HFPOBJ* obj) | |
| { | |
| HFPHED* p = GetPackHeader(curnum); | |
| return GetString(p, obj->name); | |
| } | |
| char* FilePack::GetFolderName(HFPOBJ* obj) | |
| { | |
| HFPHED* p = GetPackHeader(curnum); | |
| if (obj->folder == 0) return ""; | |
| return GetString(p, obj->folder); | |
| } | |
| int FilePack::GetFileSize(char* name) | |
| { | |
| HFPOBJ* obj; | |
| obj = SearchFileObject(name); | |
| if (obj != NULL) { | |
| return (int)obj->size; | |
| } | |
| return -1; | |
| } | |
| HFPOBJ *FilePack::SearchFileObject( HFPHED *hed, char *name ) | |
| { | |
| // ファイル情報を検索する | |
| // | |
| int i; | |
| HFPOBJ *obj; | |
| char fname[HFP_PATH_MAX + 1]; | |
| char fname_utf8[HFP_PATH_MAX + 1]; | |
| char foldername[HFP_PATH_MAX + 1]; | |
| char foldername_utf8[HFP_PATH_MAX + 1]; | |
| if (hed == NULL) return NULL; | |
| StrSplit(name, foldername, fname); // Split Path and File Name | |
| StrCase(fname); | |
| StrCase(foldername); | |
| // UTF8に変換する | |
| hsp3_to_utf8(fname_utf8, fname, HFP_PATH_MAX); | |
| hsp3_to_utf8(foldername_utf8, foldername, HFP_PATH_MAX); | |
| obj = (HFPOBJ *)(hed+1); | |
| for(i=0;i<hed->max_file;i++) { | |
| bool fchk = true; | |
| if (obj->folder != 0) { | |
| if (strcmp(foldername_utf8, GetFolderName(obj)) != 0) fchk = false; | |
| } | |
| else { | |
| if (*foldername != 0) fchk = false; | |
| } | |
| if (fchk) { | |
| if (strcmp(fname_utf8, GetFileName(obj)) == 0) return obj; | |
| } | |
| obj++; | |
| } | |
| return NULL; | |
| } | |
| HFPOBJ* FilePack::SearchFileObject(char* name) | |
| { | |
| int i; | |
| HFPOBJ* obj; | |
| int baknum = GetPackSlot(); | |
| for (i = 0; i < HFP_MAX; i++) { | |
| HFPHED* hed = buf[i]; | |
| if (hed) { | |
| SetCurrentSlot(i); | |
| obj = SearchFileObject(hed, name); | |
| if (obj != NULL) { | |
| return obj; | |
| } | |
| } | |
| } | |
| SetCurrentSlot(baknum); | |
| return NULL; | |
| } | |
| int FilePack::pack_fread(char* name, void* mem, int size, int seekofs) | |
| { | |
| FILE *pt = pack_fopen(name, seekofs); | |
| if (pt == NULL) { | |
| return hsp3_rawload(name, mem, size, seekofs); | |
| } | |
| int len = pack_fread(pt, mem, size); | |
| pack_fclose(pt); | |
| return len; | |
| } | |
| /*------------------------------------------------------------*/ | |
| /* | |
| interface (stream) | |
| */ | |
| /*------------------------------------------------------------*/ | |
| DpmFile::DpmFile() | |
| { | |
| filebase = -1; | |
| _file = NULL; | |
| filepack = NULL; | |
| } | |
| DpmFile::~DpmFile() | |
| { | |
| close(); | |
| } | |
| bool DpmFile::open(FilePack* pack, char* fname) | |
| { | |
| HFPHED* hed; | |
| HFPOBJ* obj; | |
| FILE* ff; | |
| int ofs, ofs2; | |
| filepack = pack; | |
| if (filepack == NULL) return false; | |
| cur = 0; | |
| size = 0; | |
| _file = NULL; | |
| endflag = false; | |
| baseoffset = 0; | |
| fopen_crypt = 0; | |
| obj = filepack->SearchFileObject(fname); | |
| if (obj == NULL) { | |
| ff = hsp3_fopen(fname, 0); | |
| if (ff == NULL) { | |
| return false; | |
| } | |
| _file = ff; | |
| filebase = HFP_FILEBASE_NORMAL; | |
| return true; | |
| } | |
| hed = filepack->GetCurrentHeader(); | |
| ofs = hed->filetable + (int)obj->offset; | |
| ofs2 = filepack->GetCurrentDPMOffset(); | |
| baseoffset = ofs + ofs2; | |
| if (ofs2>0) { | |
| filebase = HFP_FILEBASE_PACKEXE; | |
| } | |
| else { | |
| filebase = HFP_FILEBASE_PACKDPM; | |
| } | |
| crypt = filepack->GetCurrentCryptManager(); | |
| ff = hsp3_fopen(crypt->GetBasePath(), baseoffset ); | |
| if (ff == NULL) { | |
| filebase = -1; | |
| return false; | |
| } | |
| fopen_crypt = obj->crypt; | |
| size = (int)obj->size; | |
| if (obj->crypt) { | |
| char pathname[HFP_PATH_MAX + 1]; | |
| strcpy(pathname, filepack->GetFolderName(obj)); | |
| strcat(pathname, filepack->GetFileName(obj)); | |
| int enc_crypt = crypt->GetCRC32(pathname, strlen(pathname)); // ファイルパスを暗号キーにする | |
| enc_crypt = crypt->GetSalt(enc_crypt); | |
| if (enc_crypt == 0) enc_crypt = 1; | |
| if (enc_crypt != obj->crypt) { | |
| filebase = -1; | |
| return false; | |
| } | |
| crypt->DataSet(NULL, size, obj->crypt); | |
| crypt->SetOffset(0); | |
| } | |
| _file = ff; | |
| return true; | |
| } | |
| void DpmFile::close(void) | |
| { | |
| if (filepack == NULL) return; | |
| if (_file) { | |
| hsp3_fclose(_file); | |
| _file = NULL; | |
| } | |
| filebase = -1; | |
| filepack = NULL; | |
| endflag = true; | |
| } | |
| size_t DpmFile::read(void* mem, size_t sz, size_t count) | |
| { | |
| int readsize = (int)(sz * count); | |
| int len; | |
| if ((filepack == NULL)||(_file == NULL)) return -1; | |
| len = (int)hsp3_fread(_file, mem, readsize); | |
| if ( len <= 0 ) { | |
| len = 0; | |
| endflag = true; | |
| } | |
| if (filebase == HFP_FILEBASE_NORMAL) { | |
| cur += len; | |
| return (size_t)(len/sz); | |
| } | |
| if (fopen_crypt) { | |
| int i; | |
| unsigned char* p = (unsigned char*)mem; | |
| crypt->DataSet(NULL, size, fopen_crypt); | |
| crypt->SetOffset(cur); | |
| for (i = 0; i < len; i++) { | |
| *p = crypt->Decrypt(*p); | |
| p++; | |
| } | |
| } | |
| cur += len; | |
| if (cur >= size) { | |
| endflag = true; | |
| cur = size; | |
| } | |
| return (size_t)(len/sz); | |
| } | |
| char* DpmFile::readLine(char* str, int num) | |
| { | |
| if ((filepack == NULL) || (_file == NULL)) return NULL; | |
| /* | |
| if (filebase == HFP_FILEBASE_NORMAL) { | |
| char *res = fgets(str, num, _file); | |
| Alertf("Read ok[%s]",res); | |
| if (res) { | |
| cur += strlen(str); | |
| } else { | |
| endflag = true; | |
| } | |
| return res; | |
| } | |
| */ | |
| if (fopen_crypt) { | |
| crypt->DataSet(NULL, size, fopen_crypt); | |
| crypt->SetOffset(cur); | |
| } | |
| int i = num-1; | |
| char* p = str; | |
| int a1=0; | |
| if ((p == NULL)||(num<1)) return NULL; | |
| while (1) { | |
| if (i <= 0) break; | |
| if (size>0) { | |
| if ( cur>=size ) break; | |
| } | |
| int res = hsp3_fread(_file, &a1, 1); | |
| if ( res <= 0 ) { | |
| endflag = true; | |
| break; | |
| } | |
| cur++; | |
| i--; | |
| if (fopen_crypt) { | |
| a1 = crypt->Decrypt(a1); | |
| } | |
| *p++ = (char)a1; | |
| if (a1 == 10) { | |
| break; | |
| } | |
| } | |
| *p = 0; | |
| return str; | |
| } | |
| bool DpmFile::rewind(void) | |
| { | |
| if ((filepack == NULL) || (_file == NULL)) return false; | |
| //if (filebase == HFP_FILEBASE_NORMAL) { | |
| // ::rewind(_file); | |
| // return true; | |
| //} | |
| seek(0, SEEK_SET); | |
| return true; | |
| } | |
| bool DpmFile::seek(int offset, int origin) | |
| { | |
| if ((filepack == NULL) || (_file == NULL)) return false; | |
| //if (filebase == HFP_FILEBASE_NORMAL) { | |
| //Alertf("SEEK:%d", offset); | |
| //return hsp3_fseek(_file, offset, origin) == 0; | |
| //} | |
| int newpos; | |
| switch (origin) { | |
| case SEEK_CUR: | |
| newpos = cur; | |
| break; | |
| case SEEK_END: | |
| newpos = size; | |
| break; | |
| default: | |
| newpos = 0; | |
| break; | |
| } | |
| cur = newpos + offset; | |
| if (cur < 0) { | |
| cur = 0; | |
| } | |
| if (size > 0) { | |
| if (cur >= size) { | |
| cur = size; | |
| endflag = true; | |
| } | |
| } | |
| if (filebase == HFP_FILEBASE_NORMAL) { | |
| return hsp3_fseek(_file, cur, SEEK_SET) == 0; | |
| } | |
| hsp3_fseek(_file, baseoffset+cur, SEEK_SET); | |
| return true; | |
| } | |
| bool DpmFile::eof(void) | |
| { | |
| if ((filepack == NULL) || (_file == NULL)) return true; | |
| if (filebase == HFP_FILEBASE_NORMAL) { | |
| //int res = feof(_file); | |
| //Alertf("eof %d",res); | |
| //if (res) return true; | |
| //return ((size_t)position()) >= length(); | |
| return endflag; | |
| } | |
| if (cur>=size) return true; | |
| return false; | |
| } | |
| int DpmFile::position(void) | |
| { | |
| if ((filepack == NULL) || (_file == NULL)) return -1; | |
| //if (filebase == HFP_FILEBASE_NORMAL) { | |
| // return ftell(_file); | |
| //} | |
| return cur; | |
| } | |
| size_t DpmFile::length(void) | |
| { | |
| if ((filepack == NULL) || (_file == NULL)) return -1; | |
| if (filebase == HFP_FILEBASE_NORMAL) { | |
| if ( size == 0 ) { | |
| } | |
| return (size_t)size; | |
| } | |
| return (size_t)size; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // hsp3utfcnv.cpp functions | |
| // | |
| #include "hsp3config.h" | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| char* hsp3ext_getdir(int id); | |
| #ifdef HSPWIN | |
| #include <windows.h> | |
| #include <tchar.h> | |
| #endif | |
| #include <ctype.h> | |
| #ifdef HSPIOS | |
| #include "iOSBridge.h" | |
| #include "../hsp3dish/ios/appengine.h" | |
| #endif | |
| #ifdef HSPNDK | |
| #include "../hsp3dish/hgio.h" | |
| #include "../appengine.h" | |
| #include "../javafunc.h" | |
| #endif | |
| #include "hsp3utfcnv.h" | |
| #ifdef HSPWIN | |
| #include "hsp3config.h" | |
| #include "supio.h" | |
| #include "hsp3ext.h" | |
| // | |
| // 変換用のテンポラリ | |
| // | |
| #define HSP3CNV_DEFSIZE 0x8000 | |
| static char* hsp3cnv_tmp = NULL; | |
| static int hsp3cnv_tmpsize = 0; | |
| static void hsp3cnv_cleartmp(void) | |
| { | |
| if (hsp3cnv_tmp) { | |
| free(hsp3cnv_tmp); | |
| hsp3cnv_tmp = NULL; | |
| } | |
| hsp3cnv_tmpsize = 0; | |
| } | |
| static char* hsp3cnv_gettmp(int size) | |
| { | |
| int newsize = size + 1; | |
| if (newsize < HSP3CNV_DEFSIZE) { | |
| newsize = HSP3CNV_DEFSIZE; | |
| } | |
| if (newsize > hsp3cnv_tmpsize) { | |
| hsp3cnv_cleartmp(); | |
| hsp3cnv_tmpsize = newsize; | |
| hsp3cnv_tmp = (char *)malloc(hsp3cnv_tmpsize); | |
| } | |
| return hsp3cnv_tmp; | |
| } | |
| // | |
| // API用の文字エンコードへ変換 | |
| // | |
| #ifdef HSPUTF8 | |
| HSPAPICHAR *chartoapichar( const char *orig,HSPAPICHAR **pphac) | |
| { | |
| int reslen; | |
| wchar_t *resw; | |
| if (orig == 0) { | |
| *pphac = 0; | |
| return 0; | |
| } | |
| reslen = MultiByteToWideChar(CP_UTF8,0,orig,-1,(LPWSTR)NULL,0); | |
| resw = (wchar_t*)calloc(reslen+1,sizeof(wchar_t)); | |
| MultiByteToWideChar(CP_UTF8,0,orig,-1,resw,reslen); | |
| *pphac = resw; | |
| return resw; | |
| } | |
| void freehac(HSPAPICHAR **pphac) | |
| { | |
| free(*pphac); | |
| *pphac = 0; | |
| } | |
| HSPCHAR *apichartohspchar( const HSPAPICHAR *orig,HSPCHAR **pphc) | |
| { | |
| int plen; | |
| HSPCHAR *p = 0; | |
| if (orig == 0) { | |
| *pphc = 0; | |
| return 0; | |
| } | |
| plen=WideCharToMultiByte(CP_UTF8,NULL,orig,-1,NULL,0,NULL,NULL); | |
| p = (HSPCHAR *)calloc(plen+1,sizeof(HSPCHAR*)); | |
| WideCharToMultiByte(CP_UTF8,NULL,orig,-1,p,plen,NULL,NULL); | |
| *pphc = p; | |
| return p; | |
| } | |
| void freehc(HSPCHAR **pphc) | |
| { | |
| free(*pphc); | |
| *pphc = 0; | |
| } | |
| HSPAPICHAR *ansichartoapichar(const char *orig, HSPAPICHAR **pphac) | |
| { | |
| int reslen; | |
| wchar_t *resw; | |
| if (orig == 0) { | |
| *pphac = 0; | |
| return 0; | |
| } | |
| reslen = MultiByteToWideChar(CP_ACP, 0, orig, -1, (LPWSTR)NULL, 0); | |
| resw = (wchar_t*)calloc(reslen + 1, sizeof(wchar_t)); | |
| MultiByteToWideChar(CP_ACP, 0, orig, -1, resw, reslen); | |
| *pphac = resw; | |
| return resw; | |
| } | |
| char *apichartoansichar(const HSPAPICHAR *orig, char **ppac) | |
| { | |
| int plen; | |
| HSPCHAR *p = 0; | |
| if (orig == 0) { | |
| *ppac = 0; | |
| return 0; | |
| } | |
| plen = WideCharToMultiByte(CP_ACP, NULL, orig, -1, NULL, 0, NULL, NULL); | |
| p = (char *)calloc(plen + 1, sizeof(char*)); | |
| WideCharToMultiByte(CP_ACP,NULL, orig, -1, p, plen, NULL, NULL); | |
| *ppac = p; | |
| return p; | |
| } | |
| void freeac(char **ppac) | |
| { | |
| free(*ppac); | |
| *ppac = 0; | |
| } | |
| #else | |
| HSPAPICHAR *chartoapichar( const char *orig,HSPAPICHAR **pphac) | |
| { | |
| *pphac = (HSPAPICHAR*)orig; | |
| return (HSPAPICHAR*)orig; | |
| } | |
| void freehac(HSPAPICHAR **pphac) | |
| { | |
| *pphac = 0; | |
| return; | |
| } | |
| HSPCHAR *apichartohspchar( const HSPAPICHAR *orig,HSPCHAR **pphc) | |
| { | |
| *pphc = (HSPAPICHAR*)orig; | |
| return (HSPCHAR*)orig; | |
| } | |
| void freehc(HSPCHAR **pphc) | |
| { | |
| *pphc = 0; | |
| return; | |
| } | |
| HSPAPICHAR *ansichartoapichar(const char *orig, HSPAPICHAR **pphac) | |
| { | |
| *pphac = (HSPAPICHAR*)orig; | |
| return (HSPAPICHAR*)orig; | |
| } | |
| char *apichartoansichar(const HSPAPICHAR *orig, char **ppc) | |
| { | |
| *ppc = (char*)orig; | |
| return (char*)orig; | |
| } | |
| void freeac(char **ppc) | |
| { | |
| *ppc = 0; | |
| return; | |
| } | |
| #endif | |
| #endif | |
| // | |
| // basic File I/O support | |
| // | |
| FILE *hsp3_fopen(char*name, int offset) | |
| { | |
| FILE* hsp3_fp = NULL; | |
| #ifdef HSPWIN | |
| #ifdef HSPUTF8 | |
| HSPAPICHAR* hactmp1; | |
| #endif | |
| #ifdef HSPUTF8 | |
| // Windows UTF | |
| hsp3_fp = _wfopen(chartoapichar(name, &hactmp1), L"rb"); | |
| freehac(&hactmp1); | |
| #else | |
| // Windows SJIS | |
| hsp3_fp = fopen(name, "rb"); | |
| #endif | |
| // Read HSPTV resource | |
| #ifdef HSPDEBUG | |
| if (hsp3_fp == NULL) { | |
| // hsptvフォルダを検索する | |
| char fn[2048]; | |
| TCHAR fporg[_MAX_PATH]; | |
| TCHAR fporg_tmp[_MAX_PATH]; | |
| char* resp8; | |
| GetModuleFileName(NULL, fporg, _MAX_PATH); | |
| getpathW(fporg, fporg_tmp, 32); | |
| apichartohspchar(fporg_tmp, &resp8); | |
| strcpy(fn, resp8); | |
| CutLastChr(fn, '\\'); | |
| freehc(&resp8); | |
| strcat(fn, "\\hsptv\\"); | |
| if ((strlen(name) + strlen(fn)) < 2047) { | |
| strcat(fn, name); | |
| #ifdef HSPUTF8 | |
| // Windows UTF | |
| hsp3_fp = _wfopen(chartoapichar(fn, &hactmp1), L"rb"); | |
| #else | |
| // Windows SJIS | |
| hsp3_fp = fopen(fn, "rb"); | |
| #endif | |
| } | |
| } | |
| #endif | |
| #else | |
| #ifdef HSPNDK | |
| { | |
| char *fname = name; | |
| if ( *name == '*' ) { | |
| fname = hgio_getstorage(name+1); | |
| } | |
| hsp3_fp = hgio_android_fopen(fname,offset); | |
| if (hsp3_fp == NULL) return NULL; | |
| return hsp3_fp; | |
| } | |
| #endif | |
| #ifdef HSPIOS | |
| { | |
| char* path = gb_filepath(name); | |
| printf("Load %s", path); | |
| hsp3_fp = fopen(path, "rb"); | |
| return hsp3_fp; | |
| } | |
| #endif | |
| // Linux | |
| hsp3_fp = fopen(name, "rb"); | |
| #ifdef HSPDEBUG | |
| if (hsp3_fp == NULL) { | |
| // hsptvフォルダを検索する | |
| char fn[2048]; | |
| strcpy(fn, hsp3ext_getdir(5)); // tv folder | |
| strcat(fn, name); | |
| hsp3_fp = fopen(fn, "rb"); | |
| } | |
| #endif | |
| #endif | |
| if (hsp3_fp == NULL) return NULL; | |
| if (offset > 0) { | |
| fseek(hsp3_fp, offset, SEEK_SET); | |
| } | |
| return hsp3_fp; | |
| } | |
| FILE* hsp3_fopenwrite(char* fname8, int offset) | |
| { | |
| FILE* hsp3_fp = NULL; | |
| #ifdef HSPWIN | |
| #ifdef HSPUTF8 | |
| // Windows UTF | |
| HSPAPICHAR* fnamew = 0; | |
| if (offset < 0) { | |
| hsp3_fp = _tfopen(chartoapichar(fname8, &fnamew), TEXT("wb")); | |
| } | |
| else { | |
| hsp3_fp = _tfopen(chartoapichar(fname8, &fnamew), TEXT("r+b")); | |
| } | |
| freehac(&fnamew); | |
| #else | |
| // Windows SJIS | |
| if (offset < 0) { | |
| hsp3_fp = fopen(fname8, "w+b"); | |
| } | |
| else { | |
| hsp3_fp = fopen(fname8, "r+b"); | |
| if (hsp3_fp == NULL) return NULL; | |
| fseek(hsp3_fp, offset, SEEK_SET); | |
| } | |
| #endif | |
| #else | |
| char *fname; | |
| fname = fname8; | |
| #ifdef HSPNDK | |
| if ( *fname != '/' ) { | |
| fname = hgio_getstorage(fname8); | |
| } | |
| #endif | |
| // Linux | |
| if (offset < 0) { | |
| hsp3_fp = fopen(fname, "w+b"); | |
| } | |
| else { | |
| hsp3_fp = fopen(fname, "r+b"); | |
| if (hsp3_fp == NULL) return NULL; | |
| fseek(hsp3_fp, offset, SEEK_SET); | |
| } | |
| #endif | |
| return hsp3_fp; | |
| } | |
| void hsp3_fclose(FILE* ptr) | |
| { | |
| #ifdef HSPNDK | |
| { | |
| return hgio_android_fclose(ptr); | |
| } | |
| #endif | |
| fclose(ptr); | |
| } | |
| int hsp3_flength(char* name) | |
| { | |
| #ifdef HSPIOS | |
| { | |
| int length = gb_existdata( name ); | |
| if (length >= 0) | |
| return length; | |
| } | |
| #endif | |
| #ifdef HSPNDK | |
| { | |
| int length = hgio_file_exist( name ); | |
| if ( length>=0 ) return length; | |
| char *fname = name; | |
| if ( *fname != '/' ) { | |
| fname = hgio_getstorage(name); | |
| } | |
| FILE* fp = fopen(fname, "rb"); | |
| if (fp) { | |
| fseek(fp, 0, SEEK_END); | |
| int length = (int)ftell(fp); | |
| fclose(fp); | |
| return length; | |
| } | |
| } | |
| #endif | |
| FILE* hsp3_fp = hsp3_fopen(name, 0); | |
| if (hsp3_fp ==NULL) { | |
| return -1; | |
| } | |
| fseek(hsp3_fp, 0, SEEK_END); | |
| int length = (int)ftell(hsp3_fp); // normal file size | |
| hsp3_fclose(hsp3_fp); | |
| return length; | |
| } | |
| int hsp3_fread( FILE* ptr, void *mem, int size ) | |
| { | |
| if (ptr == NULL) return -1; | |
| if (mem == NULL) return -1; | |
| if (size <= 0) return 0; | |
| #ifdef HSPNDK | |
| { | |
| return hgio_android_fread(ptr,mem,size); | |
| } | |
| #endif | |
| int len = (int)fread(mem, 1, size, ptr); | |
| return len; | |
| } | |
| int hsp3_fseek(FILE* ptr, int offset, int whence) | |
| { | |
| if (ptr == NULL) return -1; | |
| #ifdef HSPNDK | |
| { | |
| return hgio_android_seek(ptr,offset,whence); | |
| } | |
| #endif | |
| return fseek(ptr,offset,whence); | |
| } | |
| int hsp3_binsave( char *fname8, void *mem, int msize, int seekofs ) | |
| { | |
| FILE* hsp3_fp = hsp3_fopenwrite( fname8, seekofs ); | |
| if (hsp3_fp == NULL) return -1; | |
| int flen = (int)fwrite( mem, 1, msize, hsp3_fp); | |
| #ifdef HSPNDK | |
| fclose(hsp3_fp); | |
| return flen; | |
| #endif | |
| hsp3_fclose(hsp3_fp); | |
| #ifdef HSPWIN | |
| _fcloseall(); | |
| #endif | |
| return flen; | |
| } | |
| int hsp3_rawload(char* name, void* mem, int size, int seekofs) | |
| { | |
| #ifdef HSPNDK | |
| char *fname = name; | |
| if ( *fname != '/' ) { | |
| fname = hgio_getstorage(name); | |
| } | |
| FILE* fp = fopen(fname, "rb"); | |
| if (fp==NULL) return -1; | |
| if (seekofs > 0) { | |
| fseek(fp, seekofs, SEEK_SET); | |
| } | |
| int len = (int)fread(mem, 1, size, fp); | |
| fclose(fp); | |
| return len; | |
| #endif | |
| return -1; | |
| } | |
| // | |
| // UTF Conversion Service (Windows Only) | |
| // | |
| #ifdef HSPWIN | |
| int hsp3_to_utf16(void* out, char* in, int bufsize) | |
| { | |
| // hspchar->UTF16 に変換 | |
| // | |
| #ifdef HSPUTF8 | |
| return MultiByteToWideChar(CP_UTF8, 0, in, -1, (LPWSTR)out, bufsize); | |
| #else | |
| return MultiByteToWideChar(CP_ACP, 0, in, -1, (LPWSTR)out, bufsize); | |
| #endif | |
| } | |
| int utf16_to_hsp3(char* out, void* in, int bufsize) | |
| { | |
| // UTF16->hspchar に変換 | |
| // | |
| #ifdef HSPUTF8 | |
| return WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)in, -1, (LPSTR)out, bufsize, NULL, NULL); | |
| #else | |
| return WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)in, -1, (LPSTR)out, bufsize, NULL, NULL); | |
| #endif | |
| } | |
| #endif | |
| int hsp3_to_utf8(void* out, char* in, int bufsize) | |
| { | |
| // hspchar->UTF8 に変換 | |
| // | |
| #ifdef HSPWIN | |
| #ifdef HSPUTF8 | |
| strncpy((char*)out, in, bufsize); | |
| return -1; | |
| #else | |
| int reslen = MultiByteToWideChar(CP_ACP, 0, in, -1, (LPWSTR)NULL, 0); | |
| char* tmpbuf = hsp3cnv_gettmp(reslen); | |
| MultiByteToWideChar(CP_ACP, 0, in, -1, (LPWSTR)tmpbuf, hsp3cnv_tmpsize); | |
| return WideCharToMultiByte(CP_UTF8, 0, (LPWSTR)tmpbuf, -1, (LPSTR)out, bufsize, NULL, NULL); | |
| #endif | |
| #else | |
| strncpy((char*)out, in, bufsize); | |
| return -1; | |
| #endif | |
| } | |
| int utf8_to_hsp3(void* out, char* in, int bufsize) | |
| { | |
| // UTF8->hspchar に変換 | |
| // | |
| #ifdef HSPWIN | |
| #ifdef HSPUTF8 | |
| strncpy((char*)out, in, bufsize); | |
| return -1; | |
| #else | |
| int reslen = MultiByteToWideChar(CP_UTF8, 0, in, -1, (LPWSTR)NULL, 0); | |
| char* tmpbuf = hsp3cnv_gettmp(reslen); | |
| MultiByteToWideChar(CP_UTF8, 0, in, -1, (LPWSTR)tmpbuf, hsp3cnv_tmpsize); | |
| return WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)tmpbuf, -1, (LPSTR)out, bufsize, NULL, NULL); | |
| #endif | |
| #else | |
| strncpy((char*)out, in, bufsize); | |
| return -1; | |
| #endif | |
| } | |
| int StrCopyLetter(char* source, char* dest) | |
| { | |
| // 1文字をコピー(utf8/sjis対応版) | |
| // (移動したbyte数を返します) | |
| // | |
| unsigned char a1; | |
| unsigned char* p = (unsigned char*)source; | |
| unsigned char* dst = (unsigned char*)dest; | |
| int i = 1; | |
| a1 = *p; | |
| #ifdef HSPUTF8 | |
| if (a1 >= 128) { // 多バイト文字チェック | |
| if (a1 >= 192) i++; | |
| if (a1 >= 224) i++; | |
| if (a1 >= 240) i++; | |
| if (a1 >= 248) i++; | |
| if (a1 >= 252) i++; | |
| } | |
| #else | |
| if (a1 >= 129) { | |
| if ((a1 <= 159) || (a1 >= 224)) i++; | |
| } | |
| #endif | |
| if (dst) { | |
| int j = 0; | |
| while (1) { | |
| if (j >= i) break; | |
| *dst = *p; | |
| dst++; | |
| p++; | |
| j++; | |
| } | |
| } | |
| return i; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment