├── .clang-format ├── .gitignore ├── .vscode └── settings.json ├── AVIWrapper.cpp ├── AVIWrapper.h ├── AnimationInfo.cpp ├── AnimationInfo.h ├── BaseReader.h ├── ButtonLink.h ├── COPYING ├── DirectReader.cpp ├── DirectReader.h ├── DirtyRect.cpp ├── DirtyRect.h ├── Encoding.cpp ├── Encoding.h ├── FontInfo.cpp ├── FontInfo.h ├── LUAHandler.cpp ├── LUAHandler.h ├── Makefile.ARMLinux ├── Makefile.GP2X ├── Makefile.Linux ├── Makefile.MacOSX ├── Makefile.PSP ├── Makefile.Pandora ├── Makefile.Win ├── Makefile.WinCE ├── Makefile.iPhone ├── Makefile.iPodLinux ├── Makefile.onscripter ├── NsaReader.cpp ├── NsaReader.h ├── ONScripter.cpp ├── ONScripter.h ├── ONScripter.sln ├── ONScripter.vcxproj ├── ONScripter_animation.cpp ├── ONScripter_command.cpp ├── ONScripter_effect.cpp ├── ONScripter_effect_breakup.cpp ├── ONScripter_effect_cascade.cpp ├── ONScripter_event.cpp ├── ONScripter_file.cpp ├── ONScripter_file2.cpp ├── ONScripter_image.cpp ├── ONScripter_lut.cpp ├── ONScripter_rmenu.cpp ├── ONScripter_sound.cpp ├── ONScripter_text.cpp ├── README ├── SarReader.cpp ├── SarReader.h ├── ScriptHandler.cpp ├── ScriptHandler.h ├── ScriptParser.cpp ├── ScriptParser.h ├── ScriptParser_command.cpp ├── conv_shared.cpp ├── nsaconv.cpp ├── nsadec.cpp ├── nscriptdecode.cpp ├── onscripter_main.cpp ├── resize_image.cpp ├── resize_image.h ├── sarconv.cpp ├── sardec.cpp ├── simple_aviplay.cpp ├── sjis2utf16.cpp └── version.h /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: Google 2 | Language: Cpp 3 | 4 | AccessModifierOffset: -4 5 | AlignTrailingComments: false 6 | BreakBeforeBraces: Stroustrup 7 | ColumnLimit: 0 8 | DerivePointerAlignment: false 9 | IndentCaseLabels: false 10 | IndentWidth: 4 11 | PointerAlignment: Left 12 | SpacesBeforeTrailingComments: 1 13 | SortIncludes: false 14 | UseTab: Never 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | nsaconv 2 | nsadec 3 | onscripter 4 | sarconv 5 | sardec 6 | simple_aviplay 7 | nscriptdecode 8 | *.o 9 | *.exe 10 | *.obj 11 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.encoding": "shiftjis", 3 | "files.exclude": { 4 | "*.o": true 5 | } 6 | } -------------------------------------------------------------------------------- /AVIWrapper.cpp: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * AVIWrapper.cpp - avifile library wrapper class to play AVI video & audio stream 4 | * 5 | * Copyright (c) 2001-2014 Ogapee. All rights reserved. 6 | * 7 | * ogapee@aqua.dti2.ne.jp 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #include "AVIWrapper.h" 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #define DEFAULT_AUDIOBUF 4096 36 | #define AVI_FINISH_EVENT 12345 37 | 38 | #define AVIFILE_VERSION 747 39 | 40 | AVIWrapper::AVIWrapper() 41 | { 42 | screen_overlay = NULL; 43 | i_avi = NULL; 44 | v_stream = NULL; 45 | a_stream = NULL; 46 | remaining_buffer = new char[DEFAULT_AUDIOBUF * 4]; 47 | remaining_count = 0; 48 | } 49 | 50 | AVIWrapper::~AVIWrapper() 51 | { 52 | if (v_stream) 53 | v_stream->StopStreaming(); 54 | if (a_stream) 55 | a_stream->StopStreaming(); 56 | if (i_avi) delete i_avi; 57 | if (screen_overlay) SDL_FreeYUVOverlay(screen_overlay); 58 | if (remaining_buffer) delete[] remaining_buffer; 59 | } 60 | 61 | int AVIWrapper::init(char* filename, bool debug_flag) 62 | { 63 | this->debug_flag = debug_flag; 64 | #if AVIFILE_VERSION >= 747 65 | if (!debug_flag) avm::AvmOutput::singleton()->resetDebugLevels(-1); 66 | #else 67 | if (!debug_flag) avm::out.resetDebugLevels(-1); 68 | #endif 69 | 70 | i_avi = CreateIAviReadFile(filename); 71 | if (i_avi == NULL || i_avi->IsValid() == false) { 72 | fprintf(stderr, "can't CreateIAviReadFile from %s\n", filename); 73 | return -1; 74 | } 75 | 76 | v_stream = i_avi->GetStream(0, AviStream::Video); 77 | if (v_stream == NULL) { 78 | fprintf(stderr, "Video Stream is NULL\n"); 79 | return -1; 80 | } 81 | 82 | width = v_stream->GetStreamInfo()->GetVideoWidth(); 83 | height = v_stream->GetStreamInfo()->GetVideoHeight(); 84 | if (debug_flag) fprintf(stderr, "width %d height %d\n", width, height); 85 | 86 | return 0; 87 | } 88 | 89 | int AVIWrapper::initAV(SDL_Surface* surface, bool audio_open_flag) 90 | { 91 | screen_rect.x = screen_rect.y = 0; 92 | screen_rect.w = surface->w; 93 | screen_rect.h = surface->h; 94 | 95 | v_stream->StartStreaming(); 96 | if (v_stream->GetVideoDecoder() == NULL) { 97 | if (debug_flag) fprintf(stderr, "GetVideoDecoder() return 0.\n"); 98 | return -1; 99 | } 100 | avm::IVideoDecoder::CAPS cap = v_stream->GetVideoDecoder()->GetCapabilities(); 101 | if (debug_flag) printf("cap %x\n", cap); 102 | 103 | if (cap & avm::IVideoDecoder::CAP_YV12) { 104 | v_stream->GetVideoDecoder()->SetDestFmt(0, fccYV12); 105 | screen_overlay = SDL_CreateYUVOverlay(width, height, SDL_YV12_OVERLAY, surface); 106 | } 107 | else if (cap & avm::IVideoDecoder::CAP_YUY2) { 108 | v_stream->GetVideoDecoder()->SetDestFmt(0, fccYUY2); 109 | screen_overlay = SDL_CreateYUVOverlay(width, height, SDL_YUY2_OVERLAY, surface); 110 | } 111 | else { 112 | screen_overlay = SDL_CreateYUVOverlay(width, height, SDL_YV12_OVERLAY, surface); 113 | } 114 | 115 | if (!audio_open_flag) return 0; 116 | a_stream = i_avi->GetStream(0, AviStream::Audio); 117 | if (a_stream == NULL) { 118 | if (debug_flag) fprintf(stderr, "Audio Stream is NULL\n"); 119 | return 0; 120 | } 121 | 122 | a_stream->StartStreaming(); 123 | WAVEFORMATEX wave_fmt; 124 | a_stream->GetAudioDecoder()->GetOutputFormat(&wave_fmt); 125 | if (debug_flag) printf(" format %d ch %d sample %d bit %d avg Bps %d\n", wave_fmt.wFormatTag, wave_fmt.nChannels, wave_fmt.nSamplesPerSec, wave_fmt.wBitsPerSample, wave_fmt.nAvgBytesPerSec); 126 | 127 | if (Mix_OpenAudio(wave_fmt.nSamplesPerSec, MIX_DEFAULT_FORMAT, wave_fmt.nChannels, DEFAULT_AUDIOBUF) < 0) { 128 | fprintf(stderr, "can't open audio device\n"); 129 | a_stream->StopStreaming(); 130 | delete a_stream; 131 | a_stream = NULL; 132 | } 133 | 134 | return 0; 135 | } 136 | 137 | static void audioCallback(void* userdata, Uint8* stream, int len) 138 | { 139 | AVIWrapper& avi = *(AVIWrapper*)userdata; 140 | avi.audioCallback(userdata, stream, len); 141 | } 142 | 143 | void AVIWrapper::audioCallback(void* userdata, Uint8* stream, int len) 144 | { 145 | if (len == 0) 146 | status = AVI_STOP; 147 | 148 | size_t ocnt; 149 | size_t samples; 150 | size_t count = 0; 151 | 152 | if (remaining_count > 0) { 153 | if (remaining_count <= len) { 154 | memcpy(stream, remaining_buffer, remaining_count); 155 | count = remaining_count; 156 | len -= remaining_count; 157 | remaining_count = 0; 158 | } 159 | else { 160 | memmove(stream, remaining_buffer, len); 161 | count = len; 162 | len = 0; 163 | remaining_count -= len; 164 | return; 165 | } 166 | } 167 | 168 | while (len > 0 && !a_stream->Eof()) { 169 | a_stream->ReadFrames(remaining_buffer, (size_t)len, (size_t)len, samples, ocnt); 170 | if ((int)ocnt <= len) { 171 | memcpy(stream + count, remaining_buffer, ocnt); 172 | len -= ocnt; 173 | } 174 | else { 175 | memcpy(stream + count, remaining_buffer, len); 176 | if ((int)ocnt - len < DEFAULT_AUDIOBUF * 4 - len) { 177 | memmove(remaining_buffer, remaining_buffer + len, ocnt - len); 178 | remaining_count = ocnt - len; 179 | } 180 | else { 181 | remaining_count = 0; 182 | } 183 | len = 0; 184 | } 185 | count += ocnt; 186 | } 187 | } 188 | 189 | double AVIWrapper::getAudioTime() 190 | { 191 | if (time_start == 0) { 192 | frame_start = (v_stream) ? v_stream->GetTime() : 0.; 193 | #if AVIFILE_VERSION >= 747 194 | time_start = avm_get_time_us(); 195 | #else 196 | time_start = longcount(); 197 | #endif 198 | } 199 | 200 | if (a_stream) 201 | return a_stream->GetTime(); 202 | else 203 | #if AVIFILE_VERSION >= 747 204 | return frame_start + to_float(avm_get_time_us(), time_start); 205 | #else 206 | return frame_start + to_float(longcount(), time_start); 207 | #endif 208 | } 209 | 210 | static int playVideo(void* userdata) 211 | { 212 | AVIWrapper& avi = *(AVIWrapper*)userdata; 213 | return avi.playVideo(userdata); 214 | } 215 | 216 | #define NUM_CACHES 3 217 | int AVIWrapper::playVideo(void* userdata) 218 | { 219 | int i; 220 | 221 | struct { 222 | bool valid; 223 | avm::CImage* image; 224 | double time; 225 | } cache[NUM_CACHES]; 226 | for (i = 0; i < NUM_CACHES; i++) { 227 | cache[i].valid = false; 228 | } 229 | int remaining_cache = NUM_CACHES; 230 | 231 | while (status == AVI_PLAYING && !v_stream->Eof()) { 232 | avm::CImage* image = v_stream->GetFrame(true); 233 | if (image == NULL) break; 234 | 235 | double current_time = v_stream->GetTime(); 236 | double minimum_time = current_time; 237 | 238 | // look for the nearest in the cache 239 | int nearest_cache = -1; 240 | for (i = 0; i < NUM_CACHES; i++) { 241 | if (cache[i].valid) { 242 | if (nearest_cache == -1 || 243 | (nearest_cache >= 0 && 244 | cache[i].time < cache[nearest_cache].time)) { 245 | nearest_cache = i; 246 | if (minimum_time > cache[nearest_cache].time) 247 | minimum_time = cache[nearest_cache].time; 248 | } 249 | } 250 | } 251 | 252 | double async = getAudioTime() - minimum_time; 253 | // printf("audio %f (%f - %f) minimum %d %f cur %f\n", async, getAudioTime(), minimum_time, nearest_cache, minimum_time, current_time ); 254 | if (async < -0.01) { 255 | if (remaining_cache == 0) { 256 | // printf("sync0 %f %f %f %f\n", async, (a_stream)?a_stream->GetTime():0.0, v_stream->GetTime(), minimum_time ); 257 | SDL_Delay((int)(-async * 1000)); 258 | } 259 | } 260 | if ((async < -0.01 && remaining_cache > 0) || 261 | nearest_cache >= 0) { 262 | // add cache 263 | for (i = 0; i < NUM_CACHES; i++) { 264 | if (cache[i].valid == false) { 265 | cache[i].valid = true; 266 | cache[i].image = new avm::CImage(image); 267 | cache[i].time = current_time; 268 | remaining_cache--; 269 | break; 270 | } 271 | } 272 | if (async < -0.01) { 273 | image->Release(); 274 | continue; 275 | } 276 | } 277 | 278 | if (nearest_cache >= 0 && minimum_time == cache[nearest_cache].time) { 279 | // printf("draw cache %d %f\n", nearest_cache, cache[nearest_cache].time ); 280 | // if ( async <= 0.033 ) // drop frame if necessary 281 | drawFrame(cache[nearest_cache].image); 282 | cache[nearest_cache].image->Release(); 283 | cache[nearest_cache].valid = false; 284 | remaining_cache++; 285 | } 286 | else { 287 | // printf("draw real %f\n", current_time ); 288 | // if ( async <= 0.033 ) // drop frame if necessary 289 | drawFrame(image); 290 | } 291 | image->Release(); 292 | } 293 | status = AVI_STOP; 294 | 295 | for (i = 0; i < NUM_CACHES; i++) 296 | if (cache[i].valid) cache[i].image->Release(); 297 | 298 | return 0; 299 | } 300 | 301 | int AVIWrapper::play(bool click_flag) 302 | { 303 | int ret = 0; 304 | time_start = 0; 305 | status = AVI_PLAYING; 306 | if (v_stream) 307 | thread_id = SDL_CreateThread(::playVideo, this); 308 | if (a_stream) 309 | Mix_HookMusic(::audioCallback, this); 310 | 311 | bool done_flag = false; 312 | while (!(done_flag & click_flag) && status == AVI_PLAYING) { 313 | SDL_Event event; 314 | 315 | while (SDL_PollEvent(&event)) { 316 | switch (event.type) { 317 | case SDL_KEYUP: 318 | if (((SDL_KeyboardEvent*)&event)->keysym.sym == SDLK_RETURN || 319 | ((SDL_KeyboardEvent*)&event)->keysym.sym == SDLK_KP_ENTER || 320 | ((SDL_KeyboardEvent*)&event)->keysym.sym == SDLK_SPACE || 321 | ((SDL_KeyboardEvent*)&event)->keysym.sym == SDLK_ESCAPE) 322 | done_flag = true; 323 | break; 324 | case SDL_QUIT: 325 | ret = 1; 326 | case SDL_MOUSEBUTTONUP: 327 | done_flag = true; 328 | break; 329 | default: 330 | break; 331 | } 332 | } 333 | SDL_Delay(10); 334 | } 335 | 336 | status = AVI_STOP; 337 | if (v_stream) 338 | SDL_WaitThread(thread_id, NULL); 339 | if (a_stream) 340 | Mix_HookMusic(NULL, NULL); 341 | 342 | return ret; 343 | } 344 | 345 | int AVIWrapper::drawFrame(avm::CImage* image) 346 | { 347 | if (image == NULL) return -1; 348 | 349 | unsigned int i, j; 350 | uint32_t comp = image->GetFmt()->biCompression; 351 | 352 | unsigned char* buf = image->Data(); 353 | SDL_LockYUVOverlay(screen_overlay); 354 | Uint8* dst_y = screen_overlay->pixels[0]; 355 | Uint8* dst_u = screen_overlay->pixels[1]; 356 | Uint8* dst_v = screen_overlay->pixels[2]; 357 | 358 | if (comp == 0) { // BGR 359 | image->ToYUV(); 360 | for (i = 0; i < width * height; i++) 361 | *dst_y++ = buf[i * 3]; 362 | 363 | for (i = 0; i < height / 2; i++) { 364 | for (j = 0; j < width / 2; j++) { 365 | *dst_v++ = buf[(i * width * 2 + j * 2) * 3 + 1]; 366 | *dst_u++ = buf[(i * width * 2 + j * 2) * 3 + 2]; 367 | } 368 | } 369 | } 370 | else if (comp == IMG_FMT_YUY2) { 371 | memcpy(dst_y, buf, width * height * 2); 372 | } 373 | else if (comp == IMG_FMT_YV12) { 374 | memcpy(dst_y, buf, width * height + width * height / 2); 375 | } 376 | SDL_UnlockYUVOverlay(screen_overlay); 377 | SDL_DisplayYUVOverlay(screen_overlay, &screen_rect); 378 | 379 | return 0; 380 | } 381 | -------------------------------------------------------------------------------- /AVIWrapper.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * AVIWrapper.h - avifile library wrapper class to play AVI video & audio stream 4 | * 5 | * Copyright (c) 2001-2008 Ogapee. All rights reserved. 6 | * 7 | * ogapee@aqua.dti2.ne.jp 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #ifndef __AVI_WRAPPER_H__ 25 | #define __AVI_WRAPPER_H__ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | class AVIWrapper { 34 | public: 35 | enum { AVI_STOP = 0, 36 | AVI_PLAYING = 1 37 | }; 38 | AVIWrapper(); 39 | ~AVIWrapper(); 40 | 41 | int init(char* filename, bool debug_flag); 42 | int initAV(SDL_Surface* surface, bool audio_open_flag); 43 | int play(bool click_flag); 44 | 45 | void audioCallback(void* userdata, Uint8* stream, int len); 46 | int playVideo(void* userdata); 47 | 48 | unsigned int getWidth() { return width; }; 49 | unsigned int getHeight() { return height; }; 50 | 51 | private: 52 | double getAudioTime(); 53 | int drawFrame(avm::CImage* image); 54 | 55 | SDL_Overlay* screen_overlay; 56 | SDL_Rect screen_rect; 57 | unsigned int width; 58 | unsigned int height; 59 | 60 | IAviReadFile* i_avi; 61 | IAviReadStream* v_stream; 62 | IAviReadStream* a_stream; 63 | int remaining_count; 64 | char* remaining_buffer; 65 | 66 | bool debug_flag; 67 | int status; 68 | SDL_Thread* thread_id; 69 | int64_t time_start; 70 | double frame_start; 71 | }; 72 | 73 | #endif // __AVI_WRAPPER_H__ 74 | -------------------------------------------------------------------------------- /AnimationInfo.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * AnimationInfo.h - General image storage class of ONScripter 4 | * 5 | * Copyright (c) 2001-2019 Ogapee. All rights reserved. 6 | * 7 | * ogapee@aqua.dti2.ne.jp 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #ifndef __ANIMATION_INFO_H__ 25 | #define __ANIMATION_INFO_H__ 26 | 27 | #include 28 | #include 29 | 30 | #ifndef _SDL_pixels_h 31 | #define SDL_PIXELFORMAT_RGB565 0 32 | #define SDL_PIXELFORMAT_ABGR8888 1 33 | #define SDL_PIXELFORMAT_ARGB8888 2 34 | #endif 35 | 36 | typedef unsigned char uchar3[3]; 37 | 38 | class AnimationInfo { 39 | public: 40 | #if defined(BPP16) 41 | typedef Uint16 ONSBuf; 42 | #else 43 | typedef Uint32 ONSBuf; 44 | #endif 45 | enum { TRANS_ALPHA = 1, 46 | TRANS_TOPLEFT = 2, 47 | TRANS_COPY = 3, 48 | TRANS_STRING = 4, 49 | TRANS_DIRECT = 5, 50 | TRANS_PALLETTE = 6, 51 | TRANS_TOPRIGHT = 7, 52 | TRANS_MASK = 8 53 | }; 54 | 55 | /* variables set from the image tag */ 56 | int trans_mode; 57 | unsigned char default_alpha; 58 | uchar3 direct_color; 59 | int pallette_number; 60 | uchar3 color; 61 | SDL_Rect orig_pos; // position and size of the image before resizing 62 | SDL_Rect pos; // position and size of the current cell 63 | SDL_Rect affine_pos; // topleft position and width/height for affince transformation 64 | 65 | int num_of_cells; 66 | int current_cell; 67 | int direction; 68 | int* duration_list; 69 | uchar3* color_list; 70 | int loop_mode; 71 | bool is_animatable; 72 | bool is_single_line; 73 | bool is_tight_region; // valid under TRANS_STRING, if false, ruby is parsed 74 | bool is_ruby_drawable; 75 | bool is_2x; 76 | bool is_flipped; 77 | 78 | char* file_name; 79 | char* mask_file_name; 80 | 81 | /* Variables from AnimationInfo */ 82 | bool visible; 83 | bool abs_flag; 84 | bool affine_flag; 85 | int trans; 86 | char* image_name; 87 | char* surface_name; // used to avoid reloading images 88 | char* mask_surface_name; // used to avoid reloading images 89 | SDL_Surface* image_surface; 90 | unsigned char* alpha_buf; 91 | Uint32 texture_format; 92 | SDL_mutex* mutex; 93 | 94 | /* Variables for extended sprite (lsp2, drawsp2, etc.) */ 95 | int scale_x, scale_y, rot; 96 | int mat[2][2], inv_mat[2][2]; 97 | int corner_xy[4][2]; 98 | SDL_Rect bounding_rect; 99 | 100 | enum { BLEND_NORMAL = 0, 101 | BLEND_ADD = 1, 102 | BLEND_SUB = 2, 103 | BLEND_ADD2 = 3 104 | }; 105 | int blending_mode; 106 | int cos_i, sin_i; 107 | 108 | int font_size_xy[2]; // used by prnum and lsp string 109 | int font_pitch[2]; // used by lsp string 110 | int next_time; 111 | 112 | int param; // used by prnum and bar 113 | int max_param; // used by bar 114 | int max_width; // used by bar 115 | 116 | AnimationInfo(); 117 | AnimationInfo(const AnimationInfo& anim); 118 | ~AnimationInfo(); 119 | 120 | AnimationInfo& operator=(const AnimationInfo& anim); 121 | 122 | void scalePosXY(int screen_ratio1, int screen_ratio2) 123 | { 124 | pos.x = orig_pos.x * screen_ratio1 / screen_ratio2; 125 | pos.y = orig_pos.y * screen_ratio1 / screen_ratio2; 126 | }; 127 | void scalePosWH(int screen_ratio1, int screen_ratio2) 128 | { 129 | pos.w = orig_pos.w * screen_ratio1 / screen_ratio2; 130 | pos.h = orig_pos.h * screen_ratio1 / screen_ratio2; 131 | }; 132 | 133 | void reset(); 134 | 135 | void deleteImageName(); 136 | void setImageName(const char* name); 137 | void deleteSurface(bool delete_surface_name = true); 138 | void remove(); 139 | void removeTag(); 140 | 141 | bool proceedAnimation(int current_time); 142 | 143 | void setCell(int cell); 144 | static int doClipping(SDL_Rect* dst, SDL_Rect* clip, SDL_Rect* clipped = NULL); 145 | void blendOnSurface(SDL_Surface* dst_surface, int dst_x, int dst_y, 146 | SDL_Rect& clip, unsigned char* layer_alpha_buf, int alpha = 255); 147 | void blendOnSurface2(SDL_Surface* dst_surface, int dst_x, int dst_y, 148 | SDL_Rect& clip, unsigned char* layer_alpha_buf, int alpha = 255); 149 | void blendText(SDL_Surface* surface, int dst_x, int dst_y, 150 | SDL_Color& color, SDL_Rect* clip, bool rotate_flag); 151 | void calcAffineMatrix(); 152 | 153 | static SDL_Surface* allocSurface(int w, int h, Uint32 texture_format); 154 | static SDL_Surface* alloc32bitSurface(int w, int h, Uint32 texture_format); 155 | void allocImage(int w, int h, Uint32 texture_format); 156 | void copySurface(SDL_Surface* surface, SDL_Rect* src_rect, SDL_Rect* dst_rect = NULL); 157 | void fill(Uint8 r, Uint8 g, Uint8 b, Uint8 a); 158 | SDL_Surface* setupImageAlpha(SDL_Surface* surface, SDL_Surface* surface_m, bool has_alpha); 159 | void setImage(SDL_Surface* surface, Uint32 texture_format); 160 | unsigned char getAlpha(int x, int y); 161 | 162 | void convertFromYUV(SDL_Overlay* src); 163 | void subtract(SDL_Surface* surface, AnimationInfo* layer_info, unsigned char* layer_alpha_buf); 164 | }; 165 | 166 | #endif // __ANIMATION_INFO_H__ 167 | -------------------------------------------------------------------------------- /BaseReader.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * BaseReader.h - Base class of archive reader 4 | * 5 | * Copyright (c) 2001-2022 Ogapee. All rights reserved. 6 | * 7 | * ogapee@aqua.dti2.ne.jp 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #ifndef __BASE_READER_H__ 25 | #define __BASE_READER_H__ 26 | 27 | #include 28 | #ifdef ANDROID 29 | extern "C" int fseek_ons(FILE* stream, long offset, int whence); 30 | #define fseek fseek_ons 31 | extern "C" long ftell_ons(FILE* stream); 32 | #define ftell ftell_ons 33 | extern "C" int fgetc_ons(FILE* stream); 34 | #define fgetc fgetc_ons 35 | extern "C" char* fgets_ons(char* s, int size, FILE* stream); 36 | #define fgets fgets_ons 37 | extern "C" size_t fread_ons(void* ptr, size_t size, size_t nmemb, FILE* stream); 38 | #define fread fread_ons 39 | extern "C" FILE* fopen_ons(const char* str, const char* mode); 40 | #define fopen fopen_ons 41 | extern "C" int mkdir_ons(const char* pathname, mode_t mode); 42 | #define mkdir mkdir_ons 43 | #endif 44 | 45 | #ifndef SEEK_END 46 | #define SEEK_END 2 47 | #endif 48 | 49 | #if defined(LINUX) || defined(MACOSX) 50 | #define DELIMITER '/' 51 | #elif defined(WIN32) 52 | #define DELIMITER '\\' 53 | #elif defined(MACOS9) 54 | #define DELIMITER ':' 55 | #define RELATIVEPATH ":" 56 | #define RELATIVEPATHLENGTH 1 57 | #else 58 | #define DELIMITER '/' 59 | #endif 60 | #ifndef RELATIVEPATH 61 | #define RELATIVEPATH "" 62 | #define RELATIVEPATHLENGTH 0 63 | #endif 64 | 65 | struct BaseReader { 66 | enum { 67 | NO_COMPRESSION = 0, 68 | SPB_COMPRESSION = 1, 69 | LZSS_COMPRESSION = 2, 70 | NBZ_COMPRESSION = 4 71 | }; 72 | 73 | enum { 74 | ARCHIVE_TYPE_NONE = 0, 75 | ARCHIVE_TYPE_SAR = 1, 76 | ARCHIVE_TYPE_NSA = 2, 77 | ARCHIVE_TYPE_NS2 = 4 // new format since NScr2.91, uses ext ".ns2" 78 | }; 79 | 80 | struct FileInfo { 81 | char name[256]; 82 | int compression_type; 83 | size_t offset; 84 | size_t length; 85 | size_t original_length; 86 | }; 87 | 88 | struct ArchiveInfo { 89 | ArchiveInfo* next; 90 | FILE* file_handle; 91 | int power_resume_number; // currently only for PSP 92 | char* file_name; 93 | FileInfo* fi_list; 94 | unsigned int num_of_files; 95 | unsigned long base_offset; 96 | 97 | ArchiveInfo() 98 | { 99 | next = NULL; 100 | file_handle = NULL; 101 | power_resume_number = 0; 102 | file_name = NULL; 103 | fi_list = NULL; 104 | num_of_files = 0; 105 | } 106 | ~ArchiveInfo() 107 | { 108 | if (file_handle) fclose(file_handle); 109 | if (file_name) delete[] file_name; 110 | if (fi_list) delete[] fi_list; 111 | } 112 | }; 113 | 114 | virtual ~BaseReader(){}; 115 | 116 | virtual int open(const char* name = NULL) = 0; 117 | virtual int close() = 0; 118 | 119 | virtual const char* getArchiveName() const = 0; 120 | virtual int getNumFiles() = 0; 121 | virtual void registerCompressionType(const char* ext, int type) = 0; 122 | 123 | virtual FileInfo getFileByIndex(unsigned int index) = 0; 124 | virtual size_t getFileLength(const char* file_name) = 0; 125 | virtual size_t getFile(const char* file_name, unsigned char* buffer, int* location = NULL) = 0; 126 | }; 127 | 128 | #endif // __BASE_READER_H__ 129 | -------------------------------------------------------------------------------- /ButtonLink.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * ButtonLink.h - Base button class 4 | * 5 | * Copyright (c) 2001-2013 Ogapee. All rights reserved. 6 | * 7 | * ogapee@aqua.dti2.ne.jp 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #ifndef __BUTTON_LINK_H__ 25 | #define __BUTTON_LINK_H__ 26 | 27 | #include "AnimationInfo.h" 28 | 29 | struct ButtonLink { 30 | enum { NORMAL_BUTTON = 0, 31 | SPRITE_BUTTON = 1, 32 | LOOKBACK_BUTTON = 2, 33 | TMP_SPRITE_BUTTON = 3 34 | }; 35 | 36 | ButtonLink* next; 37 | int button_type; 38 | int no; 39 | int sprite_no; 40 | char* exbtn_ctl[3]; 41 | SDL_Rect select_rect; 42 | SDL_Rect image_rect; 43 | AnimationInfo* anim[2]; 44 | int show_flag; // 0...show nothing, 1... show anim[0], 2 ... show anim[1] 45 | 46 | ButtonLink() 47 | { 48 | button_type = NORMAL_BUTTON; 49 | next = NULL; 50 | exbtn_ctl[0] = exbtn_ctl[1] = exbtn_ctl[2] = NULL; 51 | anim[0] = anim[1] = NULL; 52 | show_flag = 0; 53 | }; 54 | 55 | ~ButtonLink() 56 | { 57 | if ((button_type == NORMAL_BUTTON || button_type == TMP_SPRITE_BUTTON) && 58 | anim[0]) delete anim[0]; 59 | for (int i = 0; i < 3; i++) 60 | if (exbtn_ctl[i]) delete[] exbtn_ctl[i]; 61 | }; 62 | 63 | void insert(ButtonLink* button) 64 | { 65 | button->next = this->next; 66 | this->next = button; 67 | }; 68 | 69 | void removeSprite(int no) 70 | { 71 | ButtonLink* bl = this; 72 | while (bl->next) { 73 | if (bl->next->sprite_no == no && 74 | bl->next->button_type == SPRITE_BUTTON) { 75 | ButtonLink* bl2 = bl->next; 76 | bl->next = bl->next->next; 77 | delete bl2; 78 | } 79 | else { 80 | bl = bl->next; 81 | } 82 | } 83 | }; 84 | }; 85 | 86 | #endif // __BUTTON_LINK_H__ 87 | -------------------------------------------------------------------------------- /DirectReader.h: -------------------------------------------------------------------------------- 1 | //$Id:$ -*- C++ -*- 2 | /* 3 | * DirectReader.h - Reader from independent files 4 | * 5 | * Copyright (c) 2001-2016 Ogapee. All rights reserved. 6 | * 7 | * ogapee@aqua.dti2.ne.jp 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #ifndef __DIRECT_READER_H__ 25 | #define __DIRECT_READER_H__ 26 | 27 | #include "BaseReader.h" 28 | #include 29 | 30 | #define MAX_FILE_NAME_LENGTH 256 31 | 32 | class DirectReader : public BaseReader { 33 | public: 34 | DirectReader(const char* path = NULL, const unsigned char* key_table = NULL); 35 | ~DirectReader(); 36 | 37 | int open(const char* name = NULL); 38 | int close(); 39 | 40 | const char* getArchiveName() const; 41 | int getNumFiles(); 42 | void registerCompressionType(const char* ext, int type); 43 | 44 | struct FileInfo getFileByIndex(unsigned int index); 45 | size_t getFileLength(const char* file_name); 46 | size_t getFile(const char* file_name, unsigned char* buffer, int* location = NULL); 47 | 48 | static void convertFromSJISToEUC(char* buf); 49 | static void convertFromSJISToUTF8(char* dst_buf, const char* src_buf); 50 | static void convertFromUTF8ToSJIS(char* dst_buf, const char* src_buf); 51 | 52 | protected: 53 | char* file_full_path; 54 | char* file_sub_path; 55 | size_t file_path_len; 56 | char* capital_name; 57 | char* capital_name_tmp; 58 | 59 | char* archive_path; 60 | unsigned char key_table[256]; 61 | bool key_table_flag; 62 | int getbit_mask; 63 | size_t getbit_len, getbit_count; 64 | unsigned char* read_buf; 65 | unsigned char* decomp_buffer; 66 | size_t decomp_buffer_len; 67 | 68 | struct RegisteredCompressionType { 69 | RegisteredCompressionType* next; 70 | char* ext; 71 | int type; 72 | RegisteredCompressionType() 73 | { 74 | ext = NULL; 75 | next = NULL; 76 | }; 77 | RegisteredCompressionType(const char* ext, int type) 78 | { 79 | this->ext = new char[strlen(ext) + 1]; 80 | for (unsigned int i = 0; i < strlen(ext) + 1; i++) { 81 | this->ext[i] = ext[i]; 82 | if (this->ext[i] >= 'a' && this->ext[i] <= 'z') 83 | this->ext[i] += 'A' - 'a'; 84 | } 85 | this->type = type; 86 | this->next = NULL; 87 | }; 88 | ~RegisteredCompressionType() 89 | { 90 | if (ext) delete[] ext; 91 | }; 92 | } root_registered_compression_type, *last_registered_compression_type; 93 | 94 | FILE* fopen(const char* path, const char* mode); 95 | unsigned char readChar(FILE* fp); 96 | unsigned short readShort(FILE* fp); 97 | unsigned long readLong(FILE* fp); 98 | void writeChar(FILE* fp, unsigned char ch); 99 | void writeShort(FILE* fp, unsigned short ch); 100 | void writeLong(FILE* fp, unsigned long ch); 101 | static unsigned short swapShort(unsigned short ch); 102 | static unsigned long swapLong(unsigned long ch); 103 | size_t decodeNBZ(FILE* fp, size_t offset, unsigned char* buf); 104 | size_t encodeNBZ(FILE* fp, size_t length, unsigned char* buf); 105 | int getbit(FILE* fp, int n); 106 | size_t decodeSPB(FILE* fp, size_t offset, unsigned char* buf); 107 | size_t decodeLZSS(struct ArchiveInfo* ai, int no, unsigned char* buf); 108 | int getRegisteredCompressionType(const char* file_name); 109 | size_t getDecompressedFileLength(int type, FILE* fp, size_t offset); 110 | 111 | private: 112 | FILE* getFileHandle(const char* file_name, int& compression_type, size_t* length); 113 | }; 114 | 115 | #endif // __DIRECT_READER_H__ 116 | -------------------------------------------------------------------------------- /DirtyRect.cpp: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * DirtyRect.cpp - Invalid region on text_surface which should be updated 4 | * 5 | * Copyright (c) 2001-2012 Ogapee. All rights reserved. 6 | * 7 | * ogapee@aqua.dti2.ne.jp 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #include "DirtyRect.h" 25 | 26 | DirtyRect::DirtyRect() 27 | { 28 | screen_width = screen_height = 0; 29 | bounding_box.w = bounding_box.h = 0; 30 | } 31 | 32 | DirtyRect::DirtyRect(const DirtyRect& d) 33 | { 34 | screen_width = d.screen_width; 35 | screen_height = d.screen_height; 36 | bounding_box = d.bounding_box; 37 | } 38 | 39 | DirtyRect& DirtyRect::operator=(const DirtyRect& d) 40 | { 41 | screen_width = d.screen_width; 42 | screen_height = d.screen_height; 43 | bounding_box = d.bounding_box; 44 | 45 | return *this; 46 | } 47 | 48 | DirtyRect::~DirtyRect() 49 | { 50 | } 51 | 52 | void DirtyRect::setDimension(int w, int h) 53 | { 54 | screen_width = w; 55 | screen_height = h; 56 | } 57 | 58 | void DirtyRect::add(SDL_Rect src) 59 | { 60 | // printf("add %d %d %d %d\n", src.x, src.y, src.w, src.h ); 61 | if (src.w == 0 || src.h == 0) return; 62 | 63 | if (src.x < 0) { 64 | if (src.w < -src.x) return; 65 | src.w += src.x; 66 | src.x = 0; 67 | } 68 | if (src.y < 0) { 69 | if (src.h < -src.y) return; 70 | src.h += src.y; 71 | src.y = 0; 72 | } 73 | 74 | if (src.x >= screen_width) return; 75 | if (src.x + src.w >= screen_width) 76 | src.w = screen_width - src.x; 77 | 78 | if (src.y >= screen_height) return; 79 | if (src.y + src.h >= screen_height) 80 | src.h = screen_height - src.y; 81 | 82 | bounding_box = calcBoundingBox(bounding_box, src); 83 | } 84 | 85 | SDL_Rect DirtyRect::calcBoundingBox(SDL_Rect src1, SDL_Rect& src2) 86 | { 87 | if (src2.w == 0 || src2.h == 0) { 88 | return src1; 89 | } 90 | if (src1.w == 0 || src1.h == 0) { 91 | return src2; 92 | } 93 | 94 | if (src1.x > src2.x) { 95 | src1.w += src1.x - src2.x; 96 | src1.x = src2.x; 97 | } 98 | if (src1.y > src2.y) { 99 | src1.h += src1.y - src2.y; 100 | src1.y = src2.y; 101 | } 102 | if (src1.x + src1.w < src2.x + src2.w) { 103 | src1.w = src2.x + src2.w - src1.x; 104 | } 105 | if (src1.y + src1.h < src2.y + src2.h) { 106 | src1.h = src2.y + src2.h - src1.y; 107 | } 108 | 109 | return src1; 110 | } 111 | 112 | void DirtyRect::clear() 113 | { 114 | bounding_box.w = bounding_box.h = 0; 115 | } 116 | 117 | void DirtyRect::fill(int w, int h) 118 | { 119 | bounding_box.x = bounding_box.y = 0; 120 | bounding_box.w = w; 121 | bounding_box.h = h; 122 | } 123 | -------------------------------------------------------------------------------- /DirtyRect.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * DirtyRect.h - Invalid region on text_surface which should be updated 4 | * 5 | * Copyright (c) 2001-2012 Ogapee. All rights reserved. 6 | * 7 | * ogapee@aqua.dti2.ne.jp 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #ifndef __DIRTY_RECT__ 25 | #define __DIRTY_RECT__ 26 | 27 | #include 28 | 29 | struct DirtyRect { 30 | DirtyRect(); 31 | DirtyRect(const DirtyRect& d); 32 | DirtyRect& operator=(const DirtyRect& d); 33 | ~DirtyRect(); 34 | 35 | void setDimension(int w, int h); 36 | void add(SDL_Rect src); 37 | void clear(); 38 | void fill(int w, int h); 39 | 40 | SDL_Rect calcBoundingBox(SDL_Rect src1, SDL_Rect& src2); 41 | 42 | int screen_width, screen_height; 43 | SDL_Rect bounding_box; 44 | }; 45 | 46 | #endif // __DIRTY_RECT__ 47 | -------------------------------------------------------------------------------- /Encoding.cpp: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * Encoding.cpp - Character encoding handler 4 | * 5 | * Copyright (c) 2019-2020 Ogapee. All rights reserved. 6 | * 7 | * ogapee@aqua.dti2.ne.jp 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #include "Encoding.h" 25 | 26 | extern unsigned short convSJIS2UTF16(unsigned short in); 27 | extern unsigned short convUTF8ToUTF16(const char** src); 28 | 29 | Encoding::Encoding() 30 | { 31 | code = CODE_CP932; 32 | } 33 | 34 | Encoding::~Encoding() 35 | { 36 | } 37 | 38 | void Encoding::setEncoding(int code) 39 | { 40 | this->code = code; 41 | } 42 | 43 | int Encoding::getBytes(unsigned char ch, int code) 44 | { 45 | if (code == -1) code = this->code; 46 | 47 | if (code == CODE_CP932) { 48 | if ((ch & 0xe0) == 0xe0 || (ch & 0xe0) == 0x80) return 2; 49 | } 50 | else { 51 | if (0 <= ch && ch < 0x80) return 1; 52 | if (0xc0 <= ch && ch < 0xe0) return 2; 53 | if (0xe0 <= ch && ch < 0xf0) return 3; 54 | if (0xf0 <= ch && ch < 0xf8) return 4; 55 | } 56 | 57 | return 1; 58 | } 59 | 60 | int Encoding::getNum(const unsigned char* buf) 61 | { 62 | int n = 0; 63 | 64 | while (buf[0] != 0) { 65 | int n2 = getBytes(buf[0]); 66 | n++; 67 | if (n2 > 1) n++; 68 | buf += n2; 69 | } 70 | 71 | return n; 72 | } 73 | 74 | char Encoding::getTextMarker() 75 | { 76 | if (code == CODE_UTF8) 77 | return '^'; 78 | 79 | return '`'; 80 | } 81 | 82 | unsigned short Encoding::getUTF16(const char* text, int code) 83 | { 84 | unsigned short unicode = 0; 85 | 86 | if (code == -1) code = this->code; 87 | 88 | if (code == CODE_CP932) { 89 | if ((text[0] & 0xe0) == 0xe0 || (text[0] & 0xe0) == 0x80) { 90 | unsigned index = ((unsigned char*)text)[0]; 91 | index = index << 8 | ((unsigned char*)text)[1]; 92 | unicode = convSJIS2UTF16(index); 93 | } 94 | else { 95 | if ((text[0] & 0xe0) == 0xa0 || (text[0] & 0xe0) == 0xc0) 96 | unicode = ((unsigned char*)text)[0] - 0xa0 + 0xff60; 97 | else 98 | unicode = text[0]; 99 | } 100 | } 101 | else { 102 | unicode = convUTF8ToUTF16(&text); 103 | } 104 | 105 | return unicode; 106 | } 107 | -------------------------------------------------------------------------------- /Encoding.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * Encoding.h - Character encoding handler 4 | * 5 | * Copyright (c) 2019-2020 Ogapee. All rights reserved. 6 | * 7 | * ogapee@aqua.dti2.ne.jp 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #ifndef __ENCODING_H__ 25 | #define __ENCODING_H__ 26 | 27 | class Encoding { 28 | public: 29 | enum { CODE_CP932 = 0, 30 | CODE_UTF8 = 1 31 | }; 32 | 33 | Encoding(); 34 | ~Encoding(); 35 | 36 | void setEncoding(int code); 37 | int getEncoding() { return code; }; 38 | 39 | char getTextMarker(); 40 | 41 | int getBytes(unsigned char ch, int code = -1); 42 | int getNum(const unsigned char* buf); 43 | 44 | unsigned short getUTF16(const char* text, int code = -1); 45 | 46 | private: 47 | int code; 48 | }; 49 | 50 | #endif // __ENCODING_H__ 51 | -------------------------------------------------------------------------------- /FontInfo.cpp: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * FontInfo.cpp - Font information storage class of ONScripter 4 | * 5 | * Copyright (c) 2001-2022 Ogapee. All rights reserved. 6 | * 7 | * ogapee@aqua.dti2.ne.jp 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #include "FontInfo.h" 25 | #include 26 | #include 27 | 28 | #if defined(PSP) 29 | #include 30 | #include 31 | extern int psp_power_resume_number; 32 | #endif 33 | 34 | static struct FontContainer { 35 | FontContainer* next; 36 | int size; 37 | TTF_Font* font[2]; 38 | #if defined(PSP) 39 | SDL_RWops* rw_ops; 40 | int power_resume_number; 41 | char name[256]; 42 | #endif 43 | 44 | FontContainer() 45 | { 46 | size = 0; 47 | next = NULL; 48 | font[0] = font[1] = NULL; 49 | #if defined(PSP) 50 | rw_ops = NULL; 51 | power_resume_number = 0; 52 | #endif 53 | }; 54 | } root_font_container; 55 | 56 | FontInfo::FontInfo() 57 | { 58 | ttf_font[0] = ttf_font[1] = NULL; 59 | 60 | color[0] = color[1] = color[2] = 0xff; 61 | on_color[0] = on_color[1] = on_color[2] = 0xff; 62 | off_color[0] = off_color[1] = off_color[2] = 0xaa; 63 | nofile_color[0] = 0x55; 64 | nofile_color[1] = 0x55; 65 | nofile_color[2] = 0x99; 66 | rubyon_flag = false; 67 | 68 | reset(NULL); 69 | } 70 | 71 | void FontInfo::reset(Encoding* enc) 72 | { 73 | this->enc = enc; 74 | tateyoko_mode = YOKO_MODE; 75 | clear(); 76 | 77 | is_bold = true; 78 | is_shadow = true; 79 | is_transparent = true; 80 | is_newline_accepted = false; 81 | 82 | is_line_space_fixed = false; 83 | } 84 | 85 | void* FontInfo::openFont(char* font_file, int ratio1, int ratio2) 86 | { 87 | int font_size = font_size_xy[1]; 88 | if (enc->getEncoding() != Encoding::CODE_UTF8 && 89 | font_size_xy[0] < font_size_xy[1]) 90 | font_size = font_size_xy[0]; 91 | 92 | FontContainer* fc = &root_font_container; 93 | while (fc->next) { 94 | if (fc->next->size == font_size) break; 95 | fc = fc->next; 96 | } 97 | if (!fc->next) { 98 | fc->next = new FontContainer(); 99 | fc->next->size = font_size; 100 | FILE* fp = fopen(font_file, "r"); 101 | if (fp == NULL) return NULL; 102 | fclose(fp); 103 | #if defined(PSP) 104 | fc->next->rw_ops = SDL_RWFromFile(font_file, "r"); 105 | fc->next->font[0] = TTF_OpenFontRW(fc->next->rw_ops, SDL_TRUE, font_size * ratio1 / ratio2); 106 | #if (SDL_TTF_MAJOR_VERSION >= 2) && (SDL_TTF_MINOR_VERSION >= 0) && (SDL_TTF_PATCHLEVEL >= 10) 107 | fc->next->font[1] = TTF_OpenFontRW(fc->next->rw_ops, SDL_TRUE, font_size * ratio1 / ratio2); 108 | TTF_SetFontOutline(fc->next->font[1], 1); 109 | #endif 110 | fc->next->power_resume_number = psp_power_resume_number; 111 | strcpy(fc->next->name, font_file); 112 | #else 113 | fp = fopen(font_file, "rb"); 114 | fseek(fp, 0, SEEK_END); 115 | long length = ftell(fp); 116 | unsigned char* buf = new unsigned char[length]; // not released 117 | fseek(fp, 0, SEEK_SET); 118 | fread(buf, 1, length, fp); 119 | fclose(fp); 120 | SDL_RWops* src = SDL_RWFromMem(buf, length); 121 | fc->next->font[0] = TTF_OpenFontRW(src, 1, font_size * ratio1 / ratio2); 122 | #if (SDL_TTF_MAJOR_VERSION >= 2) && (SDL_TTF_MINOR_VERSION >= 0) && (SDL_TTF_PATCHLEVEL >= 10) 123 | SDL_RWops* src2 = SDL_RWFromMem(buf, length); 124 | fc->next->font[1] = TTF_OpenFontRW(src2, 1, font_size * ratio1 / ratio2); 125 | TTF_SetFontOutline(fc->next->font[1], 1); 126 | #endif 127 | #endif 128 | } 129 | #if defined(PSP) 130 | else if (fc->next->power_resume_number != psp_power_resume_number) { 131 | FILE* fp = fopen(fc->next->name, "r"); 132 | fc->next->rw_ops->hidden.stdio.fp = fp; 133 | fc->next->power_resume_number = psp_power_resume_number; 134 | } 135 | #endif 136 | 137 | ttf_font[0] = (void*)fc->next->font[0]; 138 | ttf_font[1] = (void*)fc->next->font[1]; 139 | 140 | return fc->next->font; 141 | } 142 | 143 | void FontInfo::setTateyokoMode(int tateyoko_mode) 144 | { 145 | this->tateyoko_mode = tateyoko_mode; 146 | clear(); 147 | } 148 | 149 | int FontInfo::getTateyokoMode() 150 | { 151 | return tateyoko_mode; 152 | } 153 | 154 | int FontInfo::getRemainingLine() 155 | { 156 | if (tateyoko_mode == YOKO_MODE) 157 | return num_xy[1] - xy[1] / 2; 158 | else 159 | return num_xy[1] - num_xy[0] + xy[0] / 2 + 1; 160 | } 161 | 162 | void FontInfo::toggleStyle(int style) 163 | { 164 | for (int i = 0; i < 2; i++) { 165 | if (ttf_font[i] == NULL) continue; 166 | int old_style = TTF_GetFontStyle((TTF_Font*)ttf_font[i]); 167 | int new_style = old_style ^ style; 168 | TTF_SetFontStyle((TTF_Font*)ttf_font[i], new_style); 169 | } 170 | } 171 | 172 | int FontInfo::x(bool use_ruby_offset) 173 | { 174 | int x = xy[0] * pitch_xy[0] / 2 + top_xy[0] + line_offset_xy[0]; 175 | if (use_ruby_offset && rubyon_flag && tateyoko_mode == TATE_MODE) 176 | x += font_size_xy[0] - pitch_xy[0]; 177 | return x; 178 | } 179 | 180 | int FontInfo::y(bool use_ruby_offset) 181 | { 182 | int pitch_y = pitch_xy[1]; 183 | if (!is_line_space_fixed && 184 | enc->getEncoding() == Encoding::CODE_UTF8 && ttf_font[0]) 185 | pitch_y += TTF_FontLineSkip((const TTF_Font*)ttf_font[0]) - font_size_xy[1]; 186 | int y = xy[1] * pitch_y / 2 + top_xy[1] + line_offset_xy[1]; 187 | if (use_ruby_offset && rubyon_flag && tateyoko_mode == YOKO_MODE && 188 | enc->getEncoding() == Encoding::CODE_CP932) 189 | y += pitch_xy[1] - font_size_xy[1]; 190 | return y; 191 | } 192 | 193 | void FontInfo::setXY(int x, int y) 194 | { 195 | if (x != -1) xy[0] = x * 2; 196 | if (y != -1) xy[1] = y * 2; 197 | } 198 | 199 | void FontInfo::clear() 200 | { 201 | if (tateyoko_mode == YOKO_MODE) 202 | setXY(0, 0); 203 | else 204 | setXY(num_xy[0] - 1, 0); 205 | line_offset_xy[0] = line_offset_xy[1] = 0; 206 | } 207 | 208 | void FontInfo::newLine() 209 | { 210 | if (tateyoko_mode == YOKO_MODE) { 211 | xy[0] = 0; 212 | xy[1] += 2; 213 | } 214 | else { 215 | xy[0] -= 2; 216 | xy[1] = 0; 217 | } 218 | line_offset_xy[0] = line_offset_xy[1] = 0; 219 | } 220 | 221 | void FontInfo::setLineArea(const char* buf) 222 | { 223 | if (enc->getEncoding() == Encoding::CODE_UTF8) { 224 | int w = 0; 225 | while (buf[0]) { 226 | int n = enc->getBytes(buf[0]); 227 | unsigned short unicode = enc->getUTF16(buf); 228 | 229 | int minx, maxx, miny, maxy, advanced; 230 | TTF_GlyphMetrics((TTF_Font*)ttf_font[0], unicode, 231 | &minx, &maxx, &miny, &maxy, &advanced); 232 | 233 | w += advanced + pitch_xy[tateyoko_mode] - font_size_xy[tateyoko_mode]; 234 | buf += n; 235 | } 236 | num_xy[tateyoko_mode] = w * 2 / pitch_xy[tateyoko_mode] + 1; 237 | } 238 | else { 239 | num_xy[tateyoko_mode] = strlen(buf) / 2 + 1; 240 | } 241 | num_xy[1 - tateyoko_mode] = 1; 242 | } 243 | 244 | bool FontInfo::isEndOfLine(float margin) 245 | { 246 | if (xy[tateyoko_mode] + margin >= num_xy[tateyoko_mode] * 2) return true; 247 | 248 | return false; 249 | } 250 | 251 | bool FontInfo::isLineEmpty() 252 | { 253 | if (xy[tateyoko_mode] == 0) return true; 254 | 255 | return false; 256 | } 257 | 258 | void FontInfo::advanceCharInHankaku(float offset) 259 | { 260 | xy[tateyoko_mode] += offset; 261 | } 262 | 263 | void FontInfo::addLineOffset(int offset) 264 | { 265 | line_offset_xy[tateyoko_mode] += offset; 266 | } 267 | 268 | SDL_Rect FontInfo::calcUpdatedArea(int start_xy[2], int ratio1, int ratio2) 269 | { 270 | SDL_Rect rect; 271 | 272 | if (tateyoko_mode == YOKO_MODE) { 273 | int pitch_y = pitch_xy[1]; 274 | if (enc->getEncoding() == Encoding::CODE_UTF8 && ttf_font[0]) 275 | pitch_y += TTF_FontLineSkip((const TTF_Font*)ttf_font[0]) - font_size_xy[1]; 276 | if (start_xy[1] == xy[1]) { 277 | rect.x = top_xy[0] + pitch_xy[0] * start_xy[0] / 2; 278 | rect.w = pitch_xy[0] * (xy[0] - start_xy[0]) / 2 + 1; 279 | } 280 | else { 281 | rect.x = top_xy[0]; 282 | rect.w = pitch_xy[0] * num_xy[0]; 283 | } 284 | rect.y = top_xy[1] + start_xy[1] * pitch_y / 2; 285 | rect.h = pitch_y + pitch_y * (xy[1] - start_xy[1]) / 2; 286 | if (rubyon_flag && enc->getEncoding() == Encoding::CODE_CP932) 287 | rect.h += pitch_xy[1] - font_size_xy[1]; 288 | } 289 | else { 290 | rect.x = top_xy[0] + pitch_xy[0] * xy[0] / 2; 291 | rect.w = font_size_xy[0] + pitch_xy[0] * (start_xy[0] - xy[0]) / 2; 292 | if (rubyon_flag) rect.w += font_size_xy[0] - pitch_xy[0]; 293 | if (start_xy[0] == xy[0]) { 294 | rect.y = top_xy[1] + pitch_xy[1] * start_xy[1] / 2; 295 | rect.h = pitch_xy[1] * (xy[1] - start_xy[1]) / 2 + 1; 296 | } 297 | else { 298 | rect.y = top_xy[1]; 299 | rect.h = pitch_xy[1] * num_xy[1]; 300 | } 301 | num_xy[0] = (xy[0] - start_xy[0]) / 2 + 1; 302 | } 303 | 304 | return rect; 305 | } 306 | 307 | void FontInfo::addShadeArea(SDL_Rect& rect, int dx, int dy, int dw, int dh) 308 | { 309 | rect.x += dx; 310 | rect.y += dy; 311 | rect.w += dw; 312 | rect.h += dh; 313 | } 314 | 315 | int FontInfo::initRuby(FontInfo& body_info, int body_count, int ruby_count) 316 | { 317 | if ((tateyoko_mode == YOKO_MODE && 318 | body_count + body_info.xy[0] / 2 >= body_info.num_xy[0] - 1) || 319 | (tateyoko_mode == TATE_MODE && 320 | body_count + body_info.xy[1] / 2 > body_info.num_xy[1])) 321 | body_info.newLine(); 322 | 323 | top_xy[0] = body_info.x(); 324 | top_xy[1] = body_info.y(); 325 | pitch_xy[0] = font_size_xy[0]; 326 | pitch_xy[1] = font_size_xy[1]; 327 | 328 | int margin = 0; 329 | 330 | if (tateyoko_mode == YOKO_MODE) { 331 | top_xy[1] -= font_size_xy[1]; 332 | num_xy[0] = ruby_count; 333 | num_xy[1] = 1; 334 | } 335 | else { 336 | top_xy[0] += body_info.font_size_xy[0]; 337 | num_xy[0] = 1; 338 | num_xy[1] = ruby_count; 339 | } 340 | 341 | if (ruby_count * font_size_xy[tateyoko_mode] >= body_count * body_info.pitch_xy[tateyoko_mode]) { 342 | margin = (ruby_count * font_size_xy[tateyoko_mode] - body_count * body_info.pitch_xy[tateyoko_mode] + 1) / 2; 343 | } 344 | else { 345 | int offset = 0; 346 | if (ruby_count > 0) 347 | offset = (body_count * body_info.pitch_xy[tateyoko_mode] - ruby_count * font_size_xy[tateyoko_mode] + ruby_count) / (ruby_count * 2); 348 | top_xy[tateyoko_mode] += offset; 349 | pitch_xy[tateyoko_mode] += offset * 2; 350 | } 351 | body_info.line_offset_xy[tateyoko_mode] += margin; 352 | 353 | clear(); 354 | 355 | return margin; 356 | } 357 | -------------------------------------------------------------------------------- /FontInfo.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * FontInfo.h - Font information storage class of ONScripter 4 | * 5 | * Copyright (c) 2001-2020 Ogapee. All rights reserved. 6 | * 7 | * ogapee@aqua.dti2.ne.jp 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #ifndef __FONT_INFO_H__ 25 | #define __FONT_INFO_H__ 26 | 27 | #include 28 | #include "BaseReader.h" 29 | #include "Encoding.h" 30 | 31 | typedef unsigned char uchar3[3]; 32 | 33 | class FontInfo { 34 | public: 35 | enum { YOKO_MODE = 0, 36 | TATE_MODE = 1 37 | }; 38 | void* ttf_font[2]; // 0...normal rendering, 1...outline rendering 39 | uchar3 color; 40 | uchar3 on_color, off_color, nofile_color; 41 | int font_size_xy[2]; 42 | int top_xy[2]; // Top left origin 43 | int num_xy[2]; // Row and column of the text windows 44 | float xy[2]; // Current position 45 | int old_xy[2]; 46 | int pitch_xy[2]; // Width and height of a character 47 | int wait_time; 48 | bool is_bold; 49 | bool is_shadow; 50 | bool is_transparent; 51 | bool is_newline_accepted; 52 | uchar3 window_color; 53 | 54 | int line_offset_xy[2]; // ruby offset for each line 55 | bool rubyon_flag; 56 | int tateyoko_mode; 57 | Encoding* enc; // encoding 58 | bool is_line_space_fixed; 59 | 60 | FontInfo(); 61 | void reset(Encoding* enc); 62 | void* openFont(char* font_file, int ratio1, int ratio2); 63 | void setTateyokoMode(int tateyoko_mode); 64 | int getTateyokoMode(); 65 | int getRemainingLine(); 66 | void toggleStyle(int style); 67 | 68 | int x(bool use_ruby_offset = true); 69 | int y(bool use_ruby_offset = true); 70 | void setXY(int x = -1, int y = -1); 71 | void clear(); 72 | void newLine(); 73 | void setLineArea(const char* buf); 74 | 75 | bool isEndOfLine(float margin = 0.); 76 | bool isLineEmpty(); 77 | void advanceCharInHankaku(float offest); 78 | void addLineOffset(int margin); 79 | void setRubyOnFlag(bool flag); 80 | 81 | SDL_Rect calcUpdatedArea(int start_xy[2], int ratio1, int ratio2); 82 | void addShadeArea(SDL_Rect& rect, int dx, int dy, int dw, int dh); 83 | int initRuby(FontInfo& body_info, int body_count, int ruby_count); 84 | }; 85 | 86 | #endif // __FONT_INFO_H__ 87 | -------------------------------------------------------------------------------- /LUAHandler.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * LUAHandler.h - LUA handler for ONScripter 4 | * 5 | * Copyright (c) 2001-2015 Ogapee. All rights reserved. 6 | * 7 | * ogapee@aqua.dti2.ne.jp 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #if !defined(__LUA_HANDLER_H__) && defined(USE_LUA) 25 | #define __LUA_HANDLER_H__ 26 | 27 | #include 28 | 29 | class ONScripter; 30 | class ScriptHandler; 31 | 32 | class LUAHandler { 33 | public: 34 | enum { LUA_TAG, 35 | LUA_TEXT0, 36 | LUA_TEXT, 37 | LUA_ANIMATION, 38 | LUA_CLOSE, 39 | LUA_END, 40 | LUA_SAVEPOINT, 41 | LUA_SAVE, 42 | LUA_LOAD, 43 | LUA_RESET, 44 | MAX_CALLBACK 45 | }; 46 | 47 | LUAHandler(); 48 | ~LUAHandler(); 49 | 50 | void init(ONScripter* ons, ScriptHandler* sh, 51 | int screen_ratio1, int screen_ratio2); 52 | void loadInitScript(); 53 | void addCallback(const char* label); 54 | 55 | int callFunction(bool is_callback, const char* cmd, void* data = NULL); 56 | 57 | bool isCallbackEnabled(int val); 58 | 59 | bool is_animatable; 60 | int duration_time; 61 | int next_time; 62 | 63 | // private: 64 | ONScripter* ons; 65 | lua_State* state; 66 | ScriptHandler* sh; 67 | int screen_ratio1, screen_ratio2; 68 | 69 | char error_str[256]; 70 | 71 | bool callback_state[MAX_CALLBACK]; 72 | }; 73 | 74 | #endif // __LUA_HANDLER_H__ 75 | -------------------------------------------------------------------------------- /Makefile.ARMLinux: -------------------------------------------------------------------------------- 1 | # -*- Makefile -*- 2 | # 3 | # Makefile.ARMLinux - Makefile rules for linux on Zaurus 4 | # 5 | 6 | INCS = `sdl-config --cflags` 7 | 8 | # for Qtopia 9 | LIBS = -lSDL -lSDL_ttf -lSDL_image -lSDL_mixer -lbz2 -lfreetype -ljpeg -lm `sdl-config --libs` -lvorbisidec 10 | # for SL-5500, SL-A300, SL-B500, SL-C700 and SL-C750 11 | DEFS = -DLINUX -DPDA_WIDTH=640 -DBPP16 -DQWS -DUSE_OGG_VORBIS -DINTEGER_OGG_VORBIS 12 | 13 | EXESUFFIX = 14 | OBJSUFFIX = .o 15 | 16 | .SUFFIXES: 17 | .SUFFIXES: $(OBJSUFFIX) .cpp .h 18 | 19 | CC = arm-linux-g++ 20 | LD = arm-linux-g++ -o 21 | 22 | CFLAGS = -O3 -Wall -fno-exceptions -fno-rtti -fno-check-new -fomit-frame-pointer -pipe -c $(INCS) $(DEFS) 23 | RM = rm -f 24 | 25 | TARGET = onscripter$(EXESUFFIX) sarconv$(EXESUFFIX) nsaconv$(EXESUFFIX) 26 | EXT_OBJS = 27 | 28 | include Makefile.onscripter 29 | -------------------------------------------------------------------------------- /Makefile.GP2X: -------------------------------------------------------------------------------- 1 | # -*- Makefile -*- 2 | # 3 | # Makefile.GP2X - Makefile rules for GP2X 4 | # 5 | 6 | PREF = /usr/local/devkitPro/devkitGP2X 7 | 8 | INCS = `$(PREF)/bin/sdl-config --cflags` `$(PREF)/bin/freetype-config --cflags` 9 | 10 | LIBS = -static `$(PREF)/bin/sdl-config --static-libs` -lSDL_ttf -lSDL_image -lSDL_mixer -lSDL -lmikmod -lfreetype -ljpeg -lpng -lz -lbz2 -lvorbisidec 11 | 12 | DEFS = -DGP2X -DLINUX -DPDA_WIDTH=320 -DBPP16 -DUSE_OGG_VORBIS -DINTEGER_OGG_VORBIS 13 | 14 | EXESUFFIX = .gpe 15 | OBJSUFFIX = .o 16 | 17 | .SUFFIXES: 18 | .SUFFIXES: $(OBJSUFFIX) .cpp .h 19 | 20 | CC = arm-linux-g++ 21 | LD = arm-linux-g++ -o 22 | 23 | CFLAGS = -O3 -Wall -fno-exceptions -fno-rtti -fno-check-new -fomit-frame-pointer -pipe -c $(INCS) $(DEFS) 24 | RM = rm -f 25 | 26 | TARGET = onscripter$(EXESUFFIX) nsaconv$(EXESUFFIX) sarconv$(EXESUFFIX) nsadec$(EXESUFFIX) sardec$(EXESUFFIX) 27 | EXT_OBJS = 28 | 29 | include Makefile.onscripter 30 | -------------------------------------------------------------------------------- /Makefile.Linux: -------------------------------------------------------------------------------- 1 | # -*- Makefile -*- 2 | # 3 | # Makefile.Linux - Makefile rules for linux 4 | # 5 | 6 | EXESUFFIX = 7 | OBJSUFFIX = .o 8 | 9 | .SUFFIXES: 10 | .SUFFIXES: $(OBJSUFFIX) .cpp .h 11 | 12 | TARGET = onscripter$(EXESUFFIX) \ 13 | sardec$(EXESUFFIX) \ 14 | nsadec$(EXESUFFIX) \ 15 | sarconv$(EXESUFFIX) \ 16 | nsaconv$(EXESUFFIX) 17 | EXT_OBJS = 18 | 19 | # mandatory: SDL, SDL_ttf, SDL_image, SDL_mixer, bzip2, libjpeg 20 | DEFS = -DLINUX 21 | INCS = `sdl-config --cflags` 22 | LIBS = `sdl-config --libs` -lSDL_ttf -lSDL_image -lSDL_mixer -lbz2 -ljpeg -lm 23 | 24 | # recommended: smpeg 25 | DEFS += -DUSE_SMPEG 26 | INCS += `smpeg-config --cflags` 27 | LIBS += `smpeg-config --libs` 28 | 29 | # recommended: fontconfig (to get default font) 30 | DEFS += -DUSE_FONTCONFIG 31 | LIBS += -lfontconfig 32 | 33 | # recommended: OggVorbis 34 | DEFS += -DUSE_OGG_VORBIS 35 | LIBS += -logg -lvorbis -lvorbisfile 36 | 37 | # optional: Integer OggVorbis 38 | #DEFS += -DUSE_OGG_VORBIS -DINTEGER_OGG_VORBIS 39 | #LIBS += -lvorbisidec 40 | 41 | # optional: support CD audio 42 | DEFS += -DUSE_CDROM 43 | 44 | # optional: avifile 45 | DEFS += -DUSE_AVIFILE 46 | INCS += `avifile-config --cflags` 47 | LIBS += `avifile-config --libs` 48 | TARGET += simple_aviplay$(EXESUFFIX) 49 | EXT_OBJS += AVIWrapper$(OBJSUFFIX) 50 | 51 | # optional: lua 52 | DEFS += -DUSE_LUA 53 | INCS += -I/usr/include/lua5.1 54 | LIBS += -llua5.1 55 | EXT_OBJS += LUAHandler$(OBJSUFFIX) 56 | 57 | # optional: force screen width for PDA 58 | #DEFS += -DPDA_WIDTH=640 59 | 60 | # optional: enable English mode 61 | #DEFS += -DENABLE_1BYTE_CHAR -DFORCE_1BYTE_CHAR 62 | 63 | 64 | # for GNU g++ 65 | CC = g++ 66 | LD = g++ -o 67 | 68 | #CFLAGS = -g -Wall -pipe -c $(INCS) $(DEFS) 69 | CFLAGS = -O3 -Wall -fomit-frame-pointer -pipe -c $(INCS) $(DEFS) 70 | 71 | # for GCC on PowerPC specfied 72 | #CC = powerpc-unknown-linux-gnu-g++ 73 | #LD = powerpc-unknown-linux-gnu-g++ -o 74 | 75 | #CFLAGS = -O3 -mtune=G4 -maltivec -mabi=altivec -mpowerpc-gfxopt -mmultiple -mstring -Wall -fomit-frame-pointer -pipe -c $(INCS) $(DEFS) 76 | 77 | # for Intel compiler 78 | #CC = icc 79 | #LD = icc -o 80 | 81 | #CFLAGS = -O3 -tpp6 -xK -c $(INCS) $(DEFS) 82 | 83 | RM = rm -f 84 | 85 | include Makefile.onscripter 86 | -------------------------------------------------------------------------------- /Makefile.MacOSX: -------------------------------------------------------------------------------- 1 | # -*- Makefile -*- 2 | # 3 | # Makefile.MacOSX - Makefile rules for MacOS X 4 | # Thanks adas-san, Takano-san and tmkk-san 5 | # 6 | 7 | INCS = `sdl-config --cflags` `smpeg-config --cflags` 8 | 9 | LIBS = `sdl-config --libs` `smpeg-config --libs` `freetype-config --libs` -lSDL_ttf -lSDL_image -lSDL_mixer -lbz2 -lm -ljpeg -framework QuickTime -framework CoreFoundation 10 | DEFS = -DMACOSX -DUSE_CDROM -DUTF8_CAPTION -DUTF8_FILESYSTEM 11 | 12 | EXESUFFIX = 13 | OBJSUFFIX = .o 14 | 15 | .SUFFIXES: 16 | .SUFFIXES: $(OBJSUFFIX) .cpp .h 17 | 18 | CC = c++ 19 | LD = c++ -o 20 | 21 | #CFLAGS = -g -Wall -Wpointer-arith -pipe -c $(INCS) $(DEFS) 22 | CFLAGS = -O3 -Wall -Wpointer-arith -pipe -c $(INCS) $(DEFS) 23 | RM = rm -f 24 | 25 | TARGET = onscripter$(EXESUFFIX) sardec$(EXESUFFIX) nsadec$(EXESUFFIX) sarconv$(EXESUFFIX) nsaconv$(EXESUFFIX) 26 | 27 | include Makefile.onscripter 28 | -------------------------------------------------------------------------------- /Makefile.PSP: -------------------------------------------------------------------------------- 1 | # -*- Makefile -*- 2 | # 3 | # Makefile.PSP - Makefile rules for Sony Play Station Portable Firmware version 1.0 4 | # Thanks Shiikuru-san 5 | # 6 | 7 | PSPPRE = $(shell psp-config --psp-prefix) 8 | PSPDEV = $(shell psp-config --pspdev-path) 9 | PSPSDK = $(shell psp-config --pspsdk-path) 10 | 11 | INCS = $(shell $(PSPPRE)/bin/sdl-config --cflags) $(shell $(PSPPRE)/bin/freetype-config --cflags) 12 | LIBS = $(shell $(PSPPRE)/bin/sdl-config --libs) 13 | LIBS += -lSDL_ttf -lfreetype -lSDL_mixer -lSDL_image -lSDL -lSDLmain -lbz2 -ljpeg -lpng -lz -lmad -lvorbisidec 14 | 15 | # Include PSPSDK and Libc Headers 16 | INCS += -I$(PSPSDK)/include -I$(PSPDEV)/include -I$(PSPPRE)/include 17 | 18 | # Link PSPSDK and Libc Libraries 19 | LIBS += -L$(PSPSDK)/lib -L$(PSPDEV)/lib -lstdc++ -lc -lm -lpsppower -lpspnet_inet 20 | 21 | 22 | # with OggVorbis (Tremor) in PDA size (QVGA) 23 | #DEFS = -DPSP -DPDA_WIDTH=320 -DBPP16 -DMP3_MAD -DUSE_OGG_VORBIS -DINTEGER_OGG_VORBIS -DUSE_RWOPS 24 | # with OggVorbis (Tremor) in PSP size (360x270) 25 | DEFS = -DPSP -DPDA_WIDTH=360 -DBPP16 -DMP3_MAD -DUSE_OGG_VORBIS -DINTEGER_OGG_VORBIS -DUSE_RWOPS 26 | # with OggVorbis (Tremor) in PSP size (384x288) 27 | #DEFS = -DPSP -DPDA_WIDTH=384 -DBPP16 -DMP3_MAD -DUSE_OGG_VORBIS -DINTEGER_OGG_VORBIS -DUSE_RWOPS 28 | 29 | EXESUFFIX = .elf 30 | OBJSUFFIX = .o 31 | 32 | .SUFFIXES: 33 | .SUFFIXES: $(OBJSUFFIX) .cpp .h 34 | 35 | CC = psp-gcc 36 | LD = psp-gcc -o 37 | 38 | CFLAGS = -g -G0 -O3 -Wall -Wpointer-arith -fno-exceptions -fno-rtti -fno-check-new -pipe -c $(INCS) $(DEFS) 39 | RM = rm -f 40 | 41 | TARGET = EBOOT.PBP 42 | EXT_OBJS = MadWrapper$(OBJSUFFIX) 43 | 44 | 45 | # onscripter.elf -> EBOOT.PBP for PSP Firmware version 1.0 46 | 47 | FIXUP_IMPORTS = psp-fixup-imports 48 | STRIP = psp-strip 49 | MKSFO = mksfo 50 | PACK_PBP = pack-pbp 51 | 52 | PSP_TARGET = onscripter$(EXESUFFIX) 53 | PSP_TARGET_FIXUP = onscripter_fixup$(EXESUFFIX) 54 | PSP_TARGET_STRIP = onscripter_strip$(EXESUFFIX) 55 | PSP_EBOOT_TITLE = ONScripter for PSP 56 | PSP_EBOOT_SFO = PARAM.SFO 57 | PSP_EBOOT_ICON = NULL 58 | PSP_EBOOT_ICON1 = NULL 59 | PSP_EBOOT_UNKPNG = NULL 60 | PSP_EBOOT_PIC1 = NULL 61 | PSP_EBOOT_SND0 = NULL 62 | PSP_EBOOT_PSAR = NULL 63 | 64 | EBOOT.PBP : $(PSP_TARGET_STRIP) $(PSP_EBOOT_SFO) 65 | $(PACK_PBP) EBOOT.PBP $(PSP_EBOOT_SFO) $(PSP_EBOOT_ICON) \ 66 | $(PSP_EBOOT_ICON1) $(PSP_EBOOT_UNKPNG) $(PSP_EBOOT_PIC1) \ 67 | $(PSP_EBOOT_SND0) $(PSP_TARGET_STRIP) $(PSP_EBOOT_PSAR) 68 | 69 | $(PSP_EBOOT_SFO) : 70 | $(MKSFO) '$(PSP_EBOOT_TITLE)' $(PSP_EBOOT_SFO) 71 | 72 | $(PSP_TARGET_FIXUP) : $(PSP_TARGET) 73 | $(FIXUP_IMPORTS) $(PSP_TARGET) -o $(PSP_TARGET_FIXUP) 74 | 75 | $(PSP_TARGET_STRIP) : $(PSP_TARGET_FIXUP) 76 | $(STRIP) $(PSP_TARGET_FIXUP) -o $(PSP_TARGET_STRIP) 77 | 78 | include Makefile.onscripter 79 | 80 | # overriding 81 | clean : 82 | $(RM) $(TARGET) 83 | $(RM) $(PSP_TARGET) $(PSP_TARGET_FIXUP) $(PSP_TARGET_STRIP) $(PSP_EBOOT_SFO) 84 | $(RM) *.o 85 | -------------------------------------------------------------------------------- /Makefile.Pandora: -------------------------------------------------------------------------------- 1 | # -*- Makefile -*- 2 | # 3 | # Makefile.Pandora - Makefile rules for Pandora 4 | # 5 | 6 | PNDSDK = $(HOME)/pandora-dev/arm-2011.09 7 | 8 | EXESUFFIX = 9 | OBJSUFFIX = .o 10 | 11 | .SUFFIXES: 12 | .SUFFIXES: $(OBJSUFFIX) .cpp .h 13 | 14 | TARGET = onscripter$(EXESUFFIX) 15 | EXT_OBJS = 16 | 17 | # mandatory: SDL, SDL_ttf, SDL_image, SDL_mixer, bzip2, libjpeg 18 | DEFS = -DPANDORA -DLINUX -DBPP16 19 | INCS = -I$(PNDSDK)/usr/include -I$(PNDSDK)/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT 20 | LIBS = -L$(PNDSDK)/usr/lib -Wl,-rpath-link,$(PNDSDK)/usr/lib -lSDL -lpthread -lSDL_ttf -lSDL_image -lSDL_mixer -lbz2 -ljpeg -lm 21 | 22 | # recommended: smpeg 23 | DEFS += -DUSE_SMPEG 24 | INCS += -I$(PNDSDK)/usr/include/smpeg 25 | LIBS += -lsmpeg 26 | 27 | # recommended: fontconfig (to get default font) 28 | DEFS += -DUSE_FONTCONFIG 29 | LIBS += -lfontconfig 30 | 31 | # recommended: OggVorbis 32 | #DEFS += -DUSE_OGG_VORBIS 33 | #LIBS += -logg -lvorbis -lvorbisfile 34 | 35 | # optional: Integer OggVorbis 36 | DEFS += -DUSE_OGG_VORBIS -DINTEGER_OGG_VORBIS 37 | LIBS += -lvorbisidec 38 | 39 | # optional: support CD audio 40 | DEFS += -DUSE_CDROM 41 | 42 | # optional: avifile 43 | #DEFS += -DUSE_AVIFILE 44 | #INCS += `avifile-config --cflags` 45 | #LIBS += `avifile-config --libs` 46 | #TARGET += simple_aviplay$(EXESUFFIX) 47 | #EXT_OBJS += AVIWrapper$(OBJSUFFIX) 48 | 49 | # optional: lua 50 | DEFS += -DUSE_LUA 51 | INCS += -I$(PNDSDK)/usr/include 52 | LIBS += -llua -ldl 53 | EXT_OBJS += LUAHandler$(OBJSUFFIX) 54 | 55 | # optional: force screen width for PDA 56 | #DEFS += -DPDA_WIDTH=640 57 | DEFS += -DPDA_AUTOSIZE 58 | 59 | # optional: enable English mode 60 | #DEFS += -DENABLE_1BYTE_CHAR -DFORCE_1BYTE_CHAR 61 | 62 | 63 | # for GNU g++ 64 | CC = $(PNDSDK)/bin/arm-none-linux-gnueabi-g++ 65 | LD = $(PNDSDK)/bin/arm-none-linux-gnueabi-g++ -o 66 | 67 | MFLAGS = -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -ftree-vectorize -fassociative-math -funsafe-math-optimizations 68 | #CFLAGS = -g -Wall $(MFLAGS) -pipe -c $(INCS) $(DEFS) 69 | CFLAGS = -Os -Wall -fomit-frame-pointer $(MFLAGS) -pipe -c $(INCS) $(DEFS) 70 | 71 | # for GCC on PowerPC specfied 72 | #CC = powerpc-unknown-linux-gnu-g++ 73 | #LD = powerpc-unknown-linux-gnu-g++ -o 74 | 75 | #CFLAGS = -O3 -mtune=G4 -maltivec -mabi=altivec -mpowerpc-gfxopt -mmultiple -mstring -Wall -fomit-frame-pointer -pipe -c $(INCS) $(DEFS) 76 | 77 | # for Intel compiler 78 | #CC = icc 79 | #LD = icc -o 80 | 81 | #CFLAGS = -O3 -tpp6 -xK -c $(INCS) $(DEFS) 82 | 83 | RM = rm -f 84 | 85 | include Makefile.onscripter 86 | -------------------------------------------------------------------------------- /Makefile.Win: -------------------------------------------------------------------------------- 1 | # -*- Makefile -*- 2 | # 3 | # Makefile.Win - Makefile rules for windows 4 | # 5 | 6 | INCS = /I"c:\usr\include" /I"c:\usr\include\sdl" /I"c:\usr\include\smpeg" 7 | 8 | # to SDL 1.2.9 9 | #LIBS = /libpath:"c:\usr\lib" SDL.lib SDLmain.lib smpeg.lib SDL_ttf.lib SDL_image.lib SDL_mixer.lib libbz2.lib libjpeg.lib vorbisfile.lib 10 | #DEFS = /D "WIN32" /D "USE_CDROM" /D "USE_OGG_VORBIS" 11 | 12 | # from SDL 1.2.10 13 | LIBS = /libpath:"c:\usr\lib" SDL.lib SDLmain.lib smpeg.lib SDL_ttf.lib SDL_image.lib SDL_mixer.lib libbz2.lib libjpeg.lib vorbisfile.lib iconv.lib 14 | DEFS = /D "WIN32" /D "USE_CDROM" /D "USE_OGG_VORBIS" /D "UTF8_CAPTION" /D "USE_SMPEG" 15 | 16 | EXESUFFIX = .exe 17 | OBJSUFFIX = .obj 18 | 19 | .SUFFIXES: 20 | .SUFFIXES: $(OBJSUFFIX) .cpp .h 21 | 22 | CC = cl 23 | LD = link /nologo /subsystem:console /incremental:no /machine:I386 /nodefaultlib:libc /nodefaultlib:msvcrt 24 | LDOUT = /out: 25 | 26 | CFLAGS = /nologo /MT /W3 /EHsc /c /O2 $(INCS) $(DEFS) 27 | RM = del 28 | 29 | TARGET = onscripter$(EXESUFFIX) sarconv$(EXESUFFIX) nsaconv$(EXESUFFIX) 30 | 31 | !include Makefile.onscripter 32 | -------------------------------------------------------------------------------- /Makefile.WinCE: -------------------------------------------------------------------------------- 1 | # -*- Makefile -*- 2 | # 3 | # Makefile.WinCE - Makefile rules for WindowsCE 4 | # 5 | 6 | PREF = /usr/local/mingw32ce/arm-wince-mingw32ce 7 | 8 | INCS = `$(PREF)/bin/sdl-config --cflags` `$(PREF)/bin/freetype-config --cflags` 9 | 10 | LIBS = -static `$(PREF)/bin/sdl-config --libs` -lSDL_ttf -lSDL_image -lSDL_mixer -lSDL -lfreetype -ljpeg -lpng -lz -lbz2 11 | 12 | # QVGA (320x240) 13 | #DEFS = -DWINCE -DWIN32 -DPDA_WIDTH=320 -DBPP16 14 | 15 | # VGA (640x480) 16 | DEFS = -DWINCE -DWIN32 -DPDA_WIDTH=640 -DBPP16 17 | 18 | EXESUFFIX = .exe 19 | OBJSUFFIX = .o 20 | 21 | .SUFFIXES: 22 | .SUFFIXES: $(OBJSUFFIX) .cpp .h 23 | 24 | CC = arm-wince-mingw32ce-g++ -finput-charset=cp932 -fexec-charset=cp932 25 | LD = arm-wince-mingw32ce-g++ -finput-charset=cp932 -fexec-charset=cp932 -o 26 | 27 | CFLAGS = -O3 -Wall -fno-exceptions -fno-rtti -fno-check-new -fomit-frame-pointer -pipe -c $(INCS) $(DEFS) 28 | RM = rm -f 29 | 30 | TARGET = onscripter$(EXESUFFIX) 31 | EXT_OBJS = 32 | 33 | include Makefile.onscripter 34 | -------------------------------------------------------------------------------- /Makefile.iPhone: -------------------------------------------------------------------------------- 1 | # -*- Makefile -*- 2 | # 3 | # Makefile.iPhone - Makefile rules for iPhone & iPod touch 4 | # 5 | 6 | PREF = /usr/local/arm-apple-darwin 7 | 8 | INCS = `$(PREF)/bin/sdl-config --cflags` `$(PREF)/bin/freetype-config --cflags` 9 | #LIBS = `$(PREF)/bin/sdl-config --libs` -lSDL_ttf -lSDL_image -lSDL_mixer -lSDL -lvorbisidec -lfreetype -ljpeg -lpng -lbz2 -lz 10 | LIBS = `$(PREF)/bin/sdl-config --libs` \ 11 | $(PREF)/lib/libSDL_ttf.a \ 12 | $(PREF)/lib/libSDL_image.a \ 13 | $(PREF)/lib/libSDL_mixer.a \ 14 | $(PREF)/lib/libSDL.a \ 15 | $(PREF)/lib/libvorbisidec.a \ 16 | $(PREF)/lib/libfreetype.a \ 17 | $(PREF)/lib/libjpeg.a \ 18 | $(PREF)/lib/libpng.a \ 19 | -lz -lbz2 20 | 21 | DEFS = -DIPHONE -DMACOSX -DPDA_WIDTH=424 -DBPP16 -DUSE_OGG_VORBIS -DINTEGER_OGG_VORBIS -DUTF8_CAPTION -DUTF8_FILESYSTEM 22 | 23 | EXESUFFIX = 24 | OBJSUFFIX = .o 25 | 26 | .SUFFIXES: 27 | .SUFFIXES: $(OBJSUFFIX) .cpp .h 28 | 29 | CC = arm-apple-darwin-g++ 30 | LD = arm-apple-darwin-g++ -o 31 | 32 | #CFLAGS = -g -Wall -Wpointer-arith -pipe -c $(INCS) $(DEFS) 33 | CFLAGS = -O3 -Wall -Wpointer-arith -pipe -c $(INCS) $(DEFS) 34 | RM = rm -f 35 | 36 | TARGET = onscripter$(EXESUFFIX) sardec$(EXESUFFIX) nsadec$(EXESUFFIX) sarconv$(EXESUFFIX) nsaconv$(EXESUFFIX) 37 | EXT_OBJS = 38 | 39 | include Makefile.onscripter 40 | -------------------------------------------------------------------------------- /Makefile.iPodLinux: -------------------------------------------------------------------------------- 1 | # -*- Makefile -*- 2 | # 3 | # Makefile.iPodLinux - Makefile rules for uCLinux on iPod (photo/nano/video) 4 | # Thanks Shiikuru-san 5 | # 6 | # Playing movie and audio is not supported. 7 | # 8 | 9 | PREF = /usr/local/arm-uclinux-tools/arm-uclinux-elf 10 | 11 | INCS = `$(PREF)/bin/sdl-config --cflags` `$(PREF)/bin/freetype-config --cflags` 12 | 13 | LIBS = `$(PREF)/bin/sdl-config --libs` -lSDL_ttf -lSDL_image -lSDL_mixer -lSDL -lfreetype -ljpeg -lbz2 14 | 15 | # for iPod 5G (video) : 320x240 16 | #DEFS = -DIPODLINUX -DLINUX -DPDA_WIDTH=320 -DBPP16 17 | # for iPod photo : 220x176 -> 220x165 18 | #DEFS = -DIPODLINUX -DLINUX -DPDA_WIDTH=220 -DBPP16 19 | # for iPod nano : 176x132 20 | #DEFS = -DIPODLINUX -DLINUX -DPDA_WIDTH=176 -DBPP16 21 | 22 | # for iPod (nano, photo, 4G color, 5G) : Auto 23 | DEFS = -DIPODLINUX -DLINUX -DPDA_AUTOSIZE -DBPP16 24 | 25 | EXESUFFIX = 26 | OBJSUFFIX = .o 27 | 28 | .SUFFIXES: 29 | .SUFFIXES: $(OBJSUFFIX) .cpp .h 30 | 31 | CC = arm-uclinux-elf-g++ 32 | LD = arm-uclinux-elf-g++ -Wl,-elf2flt -o 33 | 34 | CFLAGS = -O3 -Wall -fno-exceptions -fno-rtti -fno-check-new -fomit-frame-pointer -pipe -c $(INCS) $(DEFS) 35 | RM = rm -f 36 | 37 | TARGET = onscripter$(EXESUFFIX) nsaconv$(EXESUFFIX) sarconv$(EXESUFFIX) nsadec$(EXESUFFIX) sardec$(EXESUFFIX) 38 | EXT_OBJS = 39 | 40 | include Makefile.onscripter 41 | -------------------------------------------------------------------------------- /Makefile.onscripter: -------------------------------------------------------------------------------- 1 | # -*- Makefile -*- 2 | # 3 | # Makefile.onscripter - General makefile rules for ONScripter 4 | # 5 | 6 | GUI_OBJS = ONScripter$(OBJSUFFIX) \ 7 | ONScripter_animation$(OBJSUFFIX) \ 8 | ONScripter_command$(OBJSUFFIX) \ 9 | ONScripter_effect$(OBJSUFFIX) \ 10 | ONScripter_effect_breakup$(OBJSUFFIX) \ 11 | ONScripter_effect_cascade$(OBJSUFFIX) \ 12 | ONScripter_event$(OBJSUFFIX) \ 13 | ONScripter_file$(OBJSUFFIX) \ 14 | ONScripter_file2$(OBJSUFFIX) \ 15 | ONScripter_image$(OBJSUFFIX) \ 16 | ONScripter_lut$(OBJSUFFIX) \ 17 | ONScripter_rmenu$(OBJSUFFIX) \ 18 | ONScripter_sound$(OBJSUFFIX) \ 19 | ONScripter_text$(OBJSUFFIX) \ 20 | AnimationInfo$(OBJSUFFIX) \ 21 | FontInfo$(OBJSUFFIX) \ 22 | DirtyRect$(OBJSUFFIX) \ 23 | Encoding$(OBJSUFFIX) \ 24 | resize_image$(OBJSUFFIX) 25 | 26 | DECODER_OBJS = DirectReader$(OBJSUFFIX) \ 27 | SarReader$(OBJSUFFIX) \ 28 | NsaReader$(OBJSUFFIX) \ 29 | sjis2utf16$(OBJSUFFIX) 30 | 31 | SARDEC_OBJS = sardec$(OBJSUFFIX) \ 32 | DirectReader$(OBJSUFFIX) \ 33 | SarReader$(OBJSUFFIX) \ 34 | sjis2utf16$(OBJSUFFIX) 35 | 36 | SARCONV_OBJS = sarconv$(OBJSUFFIX) \ 37 | conv_shared$(OBJSUFFIX) \ 38 | resize_image$(OBJSUFFIX) \ 39 | DirectReader$(OBJSUFFIX) \ 40 | SarReader$(OBJSUFFIX) \ 41 | sjis2utf16$(OBJSUFFIX) 42 | 43 | NSADEC_OBJS = nsadec$(OBJSUFFIX) \ 44 | $(DECODER_OBJS) 45 | 46 | NSACONV_OBJS = nsaconv$(OBJSUFFIX) \ 47 | conv_shared$(OBJSUFFIX) \ 48 | resize_image$(OBJSUFFIX) \ 49 | $(DECODER_OBJS) 50 | 51 | ONSCRIPTER_OBJS = onscripter_main$(OBJSUFFIX) \ 52 | $(DECODER_OBJS) \ 53 | ScriptHandler$(OBJSUFFIX) \ 54 | ScriptParser$(OBJSUFFIX) \ 55 | ScriptParser_command$(OBJSUFFIX) \ 56 | $(GUI_OBJS) $(EXT_OBJS) 57 | 58 | PARSER_HEADER = BaseReader.h \ 59 | ButtonLink.h \ 60 | DirectReader.h \ 61 | SarReader.h \ 62 | NsaReader.h \ 63 | ScriptHandler.h \ 64 | ScriptParser.h \ 65 | AnimationInfo.h \ 66 | FontInfo.h \ 67 | DirtyRect.h \ 68 | LUAHandler.h \ 69 | Encoding.h 70 | 71 | ONSCRIPTER_HEADER = ONScripter.h $(PARSER_HEADER) 72 | 73 | ALL: $(TARGET) 74 | 75 | sardec$(EXESUFFIX): $(SARDEC_OBJS) 76 | $(LD) $(LDOUT)$@ $(SARDEC_OBJS) $(LIBS) 77 | 78 | sarconv$(EXESUFFIX): $(SARCONV_OBJS) 79 | $(LD) $(LDOUT)$@ $(SARCONV_OBJS) $(LIBS) 80 | 81 | nsadec$(EXESUFFIX): $(NSADEC_OBJS) 82 | $(LD) $(LDOUT)$@ $(NSADEC_OBJS) $(LIBS) 83 | 84 | nsaconv$(EXESUFFIX): $(NSACONV_OBJS) 85 | $(LD) $(LDOUT)$@ $(NSACONV_OBJS) $(LIBS) 86 | 87 | simple_aviplay$(EXESUFFIX): simple_aviplay$(OBJSUFFIX) AVIWrapper$(OBJSUFFIX) 88 | $(LD) $(LDOUT)$@ simple_aviplay$(OBJSUFFIX) AVIWrapper$(OBJSUFFIX) $(LIBS) 89 | 90 | onscripter$(EXESUFFIX): $(ONSCRIPTER_OBJS) 91 | $(LD) $(LDOUT)$@ $(ONSCRIPTER_OBJS) $(LIBS) 92 | 93 | clean: 94 | -$(RM) $(TARGET) 95 | -$(RM) *$(OBJSUFFIX) 96 | 97 | .cpp$(OBJSUFFIX): 98 | $(CC) $(CFLAGS) $< 99 | 100 | SarReader$(OBJSUFFIX): BaseReader.h SarReader.h 101 | NsaReader$(OBJSUFFIX): BaseReader.h SarReader.h NsaReader.h 102 | DirectReader$(OBJSUFFIX): BaseReader.h DirectReader.h 103 | ScriptHandler$(OBJSUFFIX): ScriptHandler.h Encoding.h 104 | ScriptParser$(OBJSUFFIX): $(PARSER_HEADER) 105 | ScriptParser_command$(OBJSUFFIX): $(PARSER_HEADER) 106 | 107 | sardec$(OBJSUFFIX): BaseReader.h SarReader.h 108 | sarconv$(OBJSUFFIX): BaseReader.h SarReader.h 109 | nsadec$(OBJSUFFIX): BaseReader.h SarReader.h NsaReader.h 110 | nsaconv$(OBJSUFFIX): BaseReader.h SarReader.h NsaReader.h 111 | simple_aviplay$(OBJSUFFIX): AVIWrapper.h 112 | conv_shared$(OBJSUFFIX): resize_image.h 113 | 114 | onscripter_main$(OBJSUFFIX): $(ONSCRIPTER_HEADER) version.h 115 | ONScripter$(OBJSUFFIX): $(ONSCRIPTER_HEADER) 116 | ONScripter_command$(OBJSUFFIX): $(ONSCRIPTER_HEADER) version.h 117 | ONScripter_text$(OBJSUFFIX): $(ONSCRIPTER_HEADER) 118 | ONScripter_effect$(OBJSUFFIX): $(ONSCRIPTER_HEADER) 119 | ONScripter_effect_breakup$(OBJSUFFIX): $(ONSCRIPTER_HEADER) 120 | ONScripter_event$(OBJSUFFIX): $(ONSCRIPTER_HEADER) 121 | ONScripter_rmenu$(OBJSUFFIX): $(ONSCRIPTER_HEADER) 122 | ONScripter_animation$(OBJSUFFIX): $(ONSCRIPTER_HEADER) 123 | ONScripter_sound$(OBJSUFFIX): $(ONSCRIPTER_HEADER) 124 | ONScripter_file$(OBJSUFFIX): $(ONSCRIPTER_HEADER) 125 | ONScripter_file2$(OBJSUFFIX): $(ONSCRIPTER_HEADER) 126 | ONScripter_image$(OBJSUFFIX): $(ONSCRIPTER_HEADER) resize_image.h 127 | ONScripter_lut$(OBJSUFFIX): $(ONSCRIPTER_HEADER) 128 | AnimationInfo$(OBJSUFFIX): AnimationInfo.h 129 | FontInfo$(OBJSUFFIX): FontInfo.h Encoding.h 130 | DirtyRect$(OBJSUFFIX) : DirtyRect.h 131 | AVIWrapper$(OBJSUFFIX): AVIWrapper.h 132 | LUAHandler$(OBJSUFFIX): $(ONSCRIPTER_HEADER) LUAHandler.h 133 | -------------------------------------------------------------------------------- /NsaReader.cpp: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * NsaReader.cpp - Reader from a NSA archive 4 | * 5 | * Copyright (c) 2001-2019 Ogapee. All rights reserved. 6 | * 7 | * ogapee@aqua.dti2.ne.jp 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #include "NsaReader.h" 25 | #include 26 | 27 | NsaReader::NsaReader(unsigned int nsa_offset, char* path, int archive_type, const unsigned char* key_table) 28 | : SarReader(path, key_table) 29 | { 30 | sar_flag = true; 31 | this->nsa_offset = nsa_offset; 32 | this->archive_type = archive_type; 33 | num_of_nsa_archives[0] = 0; 34 | num_of_nsa_archives[1] = 0; 35 | num_of_ns2_archives = 0; 36 | 37 | if (key_table) 38 | nsa_archive_ext = "___"; 39 | else 40 | nsa_archive_ext = "nsa"; 41 | 42 | ns2_archive_ext = "ns2"; 43 | } 44 | 45 | NsaReader::~NsaReader() 46 | { 47 | } 48 | 49 | int NsaReader::open(const char* nsa_path) 50 | { 51 | bool archive_found = false; 52 | char archive_name[256]; 53 | 54 | if (!SarReader::open("arc.sar")) return 0; 55 | 56 | sar_flag = false; 57 | 58 | if (archive_type & ARCHIVE_TYPE_NS2) { 59 | for (int i = 0; i < MAX_NS2_ARCHIVE; i++) { 60 | sprintf(archive_name, "%s%02d.%s", nsa_path ? nsa_path : "", i, ns2_archive_ext); 61 | if ((archive_info_ns2[i].file_handle = fopen(archive_name, "rb")) == NULL) break; 62 | 63 | ArchiveInfo* ai = &archive_info_ns2[i]; 64 | archive_found = true; 65 | ai->file_name = new char[strlen(archive_name) + 1]; 66 | memcpy(ai->file_name, archive_name, strlen(archive_name) + 1); 67 | readArchive(ai, ARCHIVE_TYPE_NS2, nsa_offset); 68 | num_of_ns2_archives = i + 1; 69 | } 70 | } 71 | 72 | if (num_of_ns2_archives == 0 && archive_type & ARCHIVE_TYPE_NSA) { 73 | for (int k = 0; k < 2; k++) { 74 | for (int i = -1; i < MAX_EXTRA_ARCHIVE; i++) { 75 | ArchiveInfo* ai; 76 | 77 | if (i == -1) { 78 | sprintf(archive_name, "%s%sarc.%s", nsa_path ? nsa_path : "", k == 0 ? "patch/" : "", nsa_archive_ext); 79 | ai = k == 0 ? (&archive_info_patch) : (&archive_info); 80 | } 81 | else { 82 | sprintf(archive_name, "%s%sarc%d.%s", nsa_path ? nsa_path : "", k == 0 ? "patch/" : "", i + 1, nsa_archive_ext); 83 | ai = &archive_info2[k][i]; 84 | } 85 | 86 | if ((ai->file_handle = fopen(archive_name, "rb")) == NULL) break; 87 | 88 | archive_found = true; 89 | ai->file_name = new char[strlen(archive_name) + 1]; 90 | memcpy(ai->file_name, archive_name, strlen(archive_name) + 1); 91 | readArchive(ai, ARCHIVE_TYPE_NSA, nsa_offset); 92 | num_of_nsa_archives[k] = i + 1; 93 | } 94 | } 95 | } 96 | 97 | if (!archive_found) return -1; 98 | 99 | return 0; 100 | } 101 | 102 | int NsaReader::openForConvert(char* nsa_name, int archive_type, unsigned int nsa_offset) 103 | { 104 | sar_flag = false; 105 | if ((archive_info.file_handle = ::fopen(nsa_name, "rb")) == NULL) { 106 | fprintf(stderr, "can't open file %s\n", nsa_name); 107 | return -1; 108 | } 109 | 110 | readArchive(&archive_info, archive_type, nsa_offset); 111 | 112 | return 0; 113 | } 114 | 115 | int NsaReader::writeHeader(FILE* fp, int archive_type, int nsa_offset) 116 | { 117 | ArchiveInfo* ai = &archive_info; 118 | return writeHeaderSub(ai, fp, archive_type, nsa_offset); 119 | } 120 | 121 | size_t NsaReader::putFile(FILE* fp, int no, size_t offset, size_t length, size_t original_length, int compression_type, bool modified_flag, unsigned char* buffer) 122 | { 123 | ArchiveInfo* ai = &archive_info; 124 | return putFileSub(ai, fp, no, offset, length, original_length, compression_type, modified_flag, buffer); 125 | } 126 | 127 | const char* NsaReader::getArchiveName() const 128 | { 129 | return "nsa"; 130 | } 131 | 132 | int NsaReader::getNumFiles() 133 | { 134 | int total = 0; 135 | 136 | ArchiveInfo* ai[2] = {&archive_info_patch, &archive_info}; 137 | for (int k = 0; k < 2; k++) { 138 | total += ai[k]->num_of_files; 139 | for (int i = 0; i < num_of_nsa_archives[k]; i++) 140 | total += archive_info2[k][i].num_of_files; 141 | } 142 | 143 | for (int i = 0; i < num_of_ns2_archives; i++) 144 | total += archive_info_ns2[i].num_of_files; 145 | 146 | return total; 147 | } 148 | 149 | size_t NsaReader::getFileLengthSub(ArchiveInfo* ai, const char* file_name) 150 | { 151 | unsigned int i = getIndexFromFile(ai, file_name); 152 | 153 | if (i == ai->num_of_files) return 0; 154 | 155 | if (ai->fi_list[i].original_length != 0) 156 | return ai->fi_list[i].original_length; 157 | 158 | int type = ai->fi_list[i].compression_type; 159 | if (type == NO_COMPRESSION) 160 | type = getRegisteredCompressionType(file_name); 161 | if (type == NBZ_COMPRESSION || type == SPB_COMPRESSION) { 162 | ai->fi_list[i].original_length = getDecompressedFileLength(type, ai->file_handle, ai->fi_list[i].offset); 163 | } 164 | 165 | return ai->fi_list[i].original_length; 166 | } 167 | 168 | size_t NsaReader::getFileLength(const char* file_name) 169 | { 170 | if (sar_flag) return SarReader::getFileLength(file_name); 171 | 172 | size_t ret; 173 | 174 | if ((ret = DirectReader::getFileLength(file_name))) return ret; 175 | 176 | for (int i = 0; i < num_of_ns2_archives; i++) 177 | if ((ret = getFileLengthSub(&archive_info_ns2[i], file_name))) return ret; 178 | 179 | ArchiveInfo* ai[2] = {&archive_info_patch, &archive_info}; 180 | for (int k = 0; k < 2; k++) { 181 | if ((ret = getFileLengthSub(ai[k], file_name))) return ret; 182 | 183 | for (int i = 0; i < num_of_nsa_archives[k]; i++) 184 | if ((ret = getFileLengthSub(&archive_info2[k][i], file_name))) return ret; 185 | } 186 | 187 | return 0; 188 | } 189 | 190 | size_t NsaReader::getFile(const char* file_name, unsigned char* buffer, int* location) 191 | { 192 | size_t ret; 193 | 194 | if (sar_flag) return SarReader::getFile(file_name, buffer, location); 195 | 196 | if ((ret = DirectReader::getFile(file_name, buffer, location))) return ret; 197 | 198 | for (int i = 0; i < num_of_ns2_archives; i++) { 199 | if ((ret = getFileSub(&archive_info_ns2[i], file_name, buffer))) { 200 | if (location) *location = ARCHIVE_TYPE_NS2; 201 | return ret; 202 | } 203 | } 204 | 205 | ArchiveInfo* ai[2] = {&archive_info_patch, &archive_info}; 206 | for (int k = 0; k < 2; k++) { 207 | if ((ret = getFileSub(ai[k], file_name, buffer))) { 208 | if (location) *location = ARCHIVE_TYPE_NSA; 209 | return ret; 210 | } 211 | 212 | for (int i = 0; i < num_of_nsa_archives[k]; i++) { 213 | if ((ret = getFileSub(&archive_info2[k][i], file_name, buffer))) { 214 | if (location) *location = ARCHIVE_TYPE_NSA; 215 | return ret; 216 | } 217 | } 218 | } 219 | 220 | return 0; 221 | } 222 | 223 | NsaReader::FileInfo NsaReader::getFileByIndex(unsigned int index) 224 | { 225 | for (int i = 0; i < num_of_ns2_archives; i++) { 226 | if (index < archive_info_ns2[i].num_of_files) return archive_info_ns2[i].fi_list[index]; 227 | index -= archive_info_ns2[i].num_of_files; 228 | } 229 | 230 | ArchiveInfo* ai[2] = {&archive_info_patch, &archive_info}; 231 | for (int k = 0; k < 2; k++) { 232 | if (index < ai[k]->num_of_files) return archive_info.fi_list[index]; 233 | index -= ai[k]->num_of_files; 234 | 235 | for (int i = 0; i < num_of_nsa_archives[k]; i++) { 236 | if (index < archive_info2[k][i].num_of_files) return archive_info2[k][i].fi_list[index]; 237 | index -= archive_info2[k][i].num_of_files; 238 | } 239 | } 240 | 241 | fprintf(stderr, "NsaReader::getFileByIndex Index %d is out of range\n", index); 242 | 243 | return archive_info.fi_list[0]; 244 | } 245 | -------------------------------------------------------------------------------- /NsaReader.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * NsaReader.h - Reader from a NSA archive 4 | * 5 | * Copyright (c) 2001-2019 Ogapee. All rights reserved. 6 | * 7 | * ogapee@aqua.dti2.ne.jp 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #ifndef __NSA_READER_H__ 25 | #define __NSA_READER_H__ 26 | 27 | #include "SarReader.h" 28 | #define MAX_EXTRA_ARCHIVE 9 29 | #define MAX_NS2_ARCHIVE 100 30 | 31 | class NsaReader : public SarReader { 32 | public: 33 | NsaReader(unsigned int nsa_offset = 0, char* path = NULL, int archive_type = ARCHIVE_TYPE_NSA, const unsigned char* key_table = NULL); 34 | ~NsaReader(); 35 | 36 | int open(const char* nsa_path = NULL); 37 | const char* getArchiveName() const; 38 | int getNumFiles(); 39 | 40 | size_t getFileLength(const char* file_name); 41 | size_t getFile(const char* file_name, unsigned char* buf, int* location = NULL); 42 | FileInfo getFileByIndex(unsigned int index); 43 | 44 | int openForConvert(char* nsa_name, int archive_type = ARCHIVE_TYPE_NSA, unsigned int nsa_offset = 0); 45 | int writeHeader(FILE* fp, int archive_type = ARCHIVE_TYPE_NSA, int nsa_offset = 0); 46 | size_t putFile(FILE* fp, int no, size_t offset, size_t length, size_t original_length, int compression_type, bool modified_flag, unsigned char* buffer); 47 | 48 | private: 49 | bool sar_flag; 50 | int nsa_offset; 51 | int archive_type; 52 | int num_of_nsa_archives[2]; 53 | int num_of_ns2_archives; 54 | const char* nsa_archive_ext; 55 | const char* ns2_archive_ext; 56 | ArchiveInfo archive_info_patch; 57 | ArchiveInfo archive_info2[2][MAX_EXTRA_ARCHIVE]; 58 | ArchiveInfo archive_info_ns2[MAX_NS2_ARCHIVE]; 59 | 60 | size_t getFileLengthSub(ArchiveInfo* ai, const char* file_name); 61 | }; 62 | 63 | #endif // __NSA_READER_H__ 64 | -------------------------------------------------------------------------------- /ONScripter.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ogapee/onscripter/848a60892e4d721459e8d1051e1b8fe45164c3e9/ONScripter.cpp -------------------------------------------------------------------------------- /ONScripter.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27130.2003 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ONScripter", "ONScripter.vcxproj", "{0909A93C-2368-4B9D-AB10-E2DABA6F801E}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {0909A93C-2368-4B9D-AB10-E2DABA6F801E}.Debug|x64.ActiveCfg = Debug|x64 17 | {0909A93C-2368-4B9D-AB10-E2DABA6F801E}.Debug|x64.Build.0 = Debug|x64 18 | {0909A93C-2368-4B9D-AB10-E2DABA6F801E}.Debug|x86.ActiveCfg = Debug|Win32 19 | {0909A93C-2368-4B9D-AB10-E2DABA6F801E}.Debug|x86.Build.0 = Debug|Win32 20 | {0909A93C-2368-4B9D-AB10-E2DABA6F801E}.Release|x64.ActiveCfg = Release|x64 21 | {0909A93C-2368-4B9D-AB10-E2DABA6F801E}.Release|x64.Build.0 = Release|x64 22 | {0909A93C-2368-4B9D-AB10-E2DABA6F801E}.Release|x86.ActiveCfg = Release|Win32 23 | {0909A93C-2368-4B9D-AB10-E2DABA6F801E}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {6369BE9B-57FB-471E-9128-2A6513273697} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /ONScripter.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 15.0 53 | {0909A93C-2368-4B9D-AB10-E2DABA6F801E} 54 | Win32Proj 55 | ONScripter 56 | 10.0 57 | 58 | 59 | 60 | Application 61 | true 62 | v142 63 | Unicode 64 | 65 | 66 | Application 67 | false 68 | v142 69 | true 70 | Unicode 71 | 72 | 73 | Application 74 | true 75 | v142 76 | Unicode 77 | 78 | 79 | Application 80 | false 81 | v142 82 | true 83 | Unicode 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | true 105 | 106 | 107 | true 108 | ..\SDL-1.2.15\include;..\SDL_image-1.2.12;..\SDL_mixer-1.2.12;..\SDL_ttf-2.0.11;..\smpeg-debian-0.4.5+cvs20030824-8;..\lua-5.1.5\etc;..\lua-5.1.5\src;..\bzip2-1.0.6;$(IncludePath) 109 | ..\$(Platform)\$(Configuration);$(LibraryPath) 110 | 111 | 112 | false 113 | 114 | 115 | false 116 | ..\SDL-1.2.15\include;..\SDL_image-1.2.12;..\SDL_mixer-1.2.12;..\SDL_ttf-2.0.11;..\smpeg-debian-0.4.5+cvs20030824-8;..\lua-5.1.5\etc;..\lua-5.1.5\src;..\bzip2-1.0.6;$(IncludePath) 117 | ..\$(Platform)\$(Configuration);$(LibraryPath) 118 | 119 | 120 | 121 | Use 122 | Level3 123 | Disabled 124 | true 125 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 126 | true 127 | 128 | 129 | Console 130 | true 131 | 132 | 133 | 134 | 135 | NotUsing 136 | Level3 137 | Disabled 138 | true 139 | _DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;WIN32;USE_CDROM;USE_LUA;USE_OGG_VORBIS;UTF8_CAPTION;USE_SMPEG;%(PreprocessorDefinitions) 140 | true 141 | MultiThreadedDebug 142 | 143 | 144 | Console 145 | true 146 | SDL.lib;SDLmain.lib;SDL_image.lib;SDL_mixer.lib;smpeg.lib;SDL_ttf.lib;libbz2.lib;lua.lib;native_midi.lib;timidity.lib;freetype.lib;libjpeg.lib;libpng16.lib;zlib.lib;libogg.lib;libvorbis_static.lib;libvorbisfile_static.lib;winmm.lib;dxguid.lib;%(AdditionalDependencies) 147 | 148 | 149 | 150 | 151 | Use 152 | Level3 153 | MaxSpeed 154 | true 155 | true 156 | true 157 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 158 | true 159 | 160 | 161 | Console 162 | true 163 | true 164 | true 165 | 166 | 167 | 168 | 169 | NotUsing 170 | Level3 171 | MaxSpeed 172 | true 173 | true 174 | true 175 | NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;WIN32;USE_CDROM;USE_LUA;USE_OGG_VORBIS;UTF8_CAPTION;USE_SMPEG;%(PreprocessorDefinitions) 176 | true 177 | MultiThreaded 178 | 179 | 180 | Console 181 | true 182 | true 183 | true 184 | SDL.lib;SDLmain.lib;SDL_image.lib;SDL_mixer.lib;smpeg.lib;SDL_ttf.lib;libbz2.lib;lua.lib;native_midi.lib;timidity.lib;freetype.lib;libjpeg.lib;libpng16.lib;zlib.lib;libogg.lib;libvorbis_static.lib;libvorbisfile_static.lib;winmm.lib;dxguid.lib;%(AdditionalDependencies) 185 | 186 | 187 | 188 | 189 | 190 | -------------------------------------------------------------------------------- /ONScripter_command.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ogapee/onscripter/848a60892e4d721459e8d1051e1b8fe45164c3e9/ONScripter_command.cpp -------------------------------------------------------------------------------- /ONScripter_effect_breakup.cpp: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * ONScripter_effect_breakup.cpp 4 | * - Emulation of Takashi Toyama's "breakup.dll" NScripter plugin effect 5 | * 6 | * Copyright (c) 2008-2012 "Uncle" Mion Sonozaki 7 | * 8 | * UncleMion@gmail.com 9 | * 10 | * Copyright (c) 2001-2012 Ogapee 11 | * 12 | * ogapee@aqua.dti2.ne.jp 13 | * 14 | * This program is free software; you can redistribute it and/or modify 15 | * it under the terms of the GNU General Public License as published by 16 | * the Free Software Foundation; either version 2 of the License, or 17 | * (at your option) any later version. 18 | * 19 | * This program is distributed in the hope that it will be useful, 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | * GNU General Public License for more details. 23 | * 24 | * You should have received a copy of the GNU General Public License 25 | * along with this program; if not, write to the Free Software 26 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 27 | */ 28 | 29 | #include "ONScripter.h" 30 | 31 | #define BREAKUP_CELLWIDTH 24 32 | #define BREAKUP_CELLFORMS 16 33 | #define BREAKUP_MAX_CELL_X ((screen_width + BREAKUP_CELLWIDTH - 1) / BREAKUP_CELLWIDTH) 34 | #define BREAKUP_MAX_CELL_Y ((screen_height + BREAKUP_CELLWIDTH - 1) / BREAKUP_CELLWIDTH) 35 | #define BREAKUP_MAX_CELLS (BREAKUP_MAX_CELL_X * BREAKUP_MAX_CELL_Y) 36 | #define BREAKUP_DIRECTIONS 8 37 | #define BREAKUP_MOVE_FRAMES 40 38 | #define BREAKUP_STILL_STATE (BREAKUP_CELLFORMS - BREAKUP_CELLWIDTH / 2) 39 | 40 | #define BREAKUP_MODE_LOWER 1 41 | #define BREAKUP_MODE_LEFT 2 42 | #define BREAKUP_MODE_PILEUP 4 43 | #define BREAKUP_MODE_JUMBLE 8 44 | 45 | const int breakup_disp_x[BREAKUP_DIRECTIONS] = {-7, -7, -5, -4, -2, 1, 3, 5}; 46 | const int breakup_disp_y[BREAKUP_DIRECTIONS] = {0, 2, 4, 6, 7, 7, 6, 5}; 47 | int n_cells, tot_frames, last_frame; 48 | int breakup_mode; 49 | SDL_Rect breakup_window; // window of _cells_, not pixels 50 | 51 | void ONScripter::buildBreakupCellforms() 52 | { 53 | // build the 32x32 mask for each cellform 54 | if (breakup_cellforms) return; 55 | 56 | int w = BREAKUP_CELLWIDTH * BREAKUP_CELLFORMS; 57 | int h = BREAKUP_CELLWIDTH; 58 | breakup_cellforms = new bool[w * h]; 59 | 60 | for (int n = 0, rad2 = 1; n < BREAKUP_CELLFORMS; n++, rad2 = (n + 1) * (n + 1)) { 61 | for (int x = 0, xd = -BREAKUP_CELLWIDTH / 2; x < BREAKUP_CELLWIDTH; x++, xd++) { 62 | for (int y = 0, yd = -BREAKUP_CELLWIDTH / 2; y < BREAKUP_CELLWIDTH; y++, yd++) { 63 | if (((xd * xd + xd + yd * yd + yd) * 2 + 1) < 2 * rad2) 64 | breakup_cellforms[y * w + n * BREAKUP_CELLWIDTH + x] = true; 65 | else 66 | breakup_cellforms[y * w + n * BREAKUP_CELLWIDTH + x] = false; 67 | } 68 | } 69 | } 70 | } 71 | 72 | void ONScripter::buildBreakupMask() 73 | { 74 | // build the cell area mask for the breakup effect 75 | int w = BREAKUP_CELLWIDTH * BREAKUP_MAX_CELL_X; 76 | int h = BREAKUP_CELLWIDTH * BREAKUP_MAX_CELL_Y; 77 | if (!breakup_mask) { 78 | breakup_mask = new bool[w * h]; 79 | } 80 | 81 | SDL_LockSurface(effect_src_surface); 82 | SDL_LockSurface(effect_dst_surface); 83 | ONSBuf* buffer1 = (ONSBuf*)effect_src_surface->pixels; 84 | ONSBuf* buffer2 = (ONSBuf*)effect_dst_surface->pixels; 85 | SDL_PixelFormat* fmt = effect_dst_surface->format; 86 | int surf_w = effect_src_surface->w; 87 | int surf_h = effect_src_surface->h; 88 | int x1 = w, y1 = -1, x2 = 0, y2 = 0; 89 | for (int i = 0; i < h; ++i) { 90 | for (int j = 0; j < w; ++j) { 91 | if ((j >= surf_w) || (i >= surf_h)) { 92 | breakup_mask[i * w + j] = false; 93 | continue; 94 | } 95 | ONSBuf pix1 = buffer1[i * surf_w + j]; 96 | ONSBuf pix2 = buffer2[i * surf_w + j]; 97 | int pix1c = ((pix1 & fmt->Bmask) >> fmt->Bshift) << fmt->Bloss; 98 | int pix2c = ((pix2 & fmt->Bmask) >> fmt->Bshift) << fmt->Bloss; 99 | breakup_mask[i * w + j] = true; 100 | if (abs(pix1c - pix2c) > 8) { 101 | if (y1 < 0) y1 = i; 102 | if (j < x1) x1 = j; 103 | if (j > x2) x2 = j; 104 | y2 = i; 105 | continue; 106 | } 107 | pix1c = ((pix1 & fmt->Gmask) >> fmt->Gshift) << fmt->Gloss; 108 | pix2c = ((pix2 & fmt->Gmask) >> fmt->Gshift) << fmt->Gloss; 109 | if (abs(pix1c - pix2c) > 8) { 110 | if (y1 < 0) y1 = i; 111 | if (j < x1) x1 = j; 112 | if (j > x2) x2 = j; 113 | y2 = i; 114 | continue; 115 | } 116 | pix1c = ((pix1 & fmt->Rmask) >> fmt->Rshift) << fmt->Rloss; 117 | pix2c = ((pix2 & fmt->Rmask) >> fmt->Rshift) << fmt->Rloss; 118 | if (abs(pix1c - pix2c) > 8) { 119 | if (y1 < 0) y1 = i; 120 | if (j < x1) x1 = j; 121 | if (j > x2) x2 = j; 122 | y2 = i; 123 | continue; 124 | } 125 | pix1c = ((pix1 & fmt->Amask) >> fmt->Ashift) << fmt->Aloss; 126 | pix2c = ((pix2 & fmt->Amask) >> fmt->Ashift) << fmt->Aloss; 127 | if (abs(pix1c - pix2c) > 8) { 128 | if (y1 < 0) y1 = i; 129 | if (j < x1) x1 = j; 130 | if (j > x2) x2 = j; 131 | y2 = i; 132 | continue; 133 | } 134 | breakup_mask[i * w + j] = false; 135 | } 136 | } 137 | if (breakup_mode & BREAKUP_MODE_LEFT) 138 | x1 = 0; 139 | else 140 | x2 = surf_w - 1; 141 | if (breakup_mode & BREAKUP_MODE_LOWER) 142 | y2 = surf_h - 1; 143 | else 144 | y1 = 0; 145 | breakup_window.x = x1 / BREAKUP_CELLWIDTH; 146 | breakup_window.y = y1 / BREAKUP_CELLWIDTH; 147 | breakup_window.w = x2 / BREAKUP_CELLWIDTH - breakup_window.x + 1; 148 | breakup_window.h = y2 / BREAKUP_CELLWIDTH - breakup_window.y + 1; 149 | 150 | SDL_UnlockSurface(effect_dst_surface); 151 | SDL_UnlockSurface(effect_src_surface); 152 | } 153 | 154 | void ONScripter::initBreakup(char* params) 155 | { 156 | while (*params != 0 && *params != '/') params++; 157 | if (*params == '/') params++; 158 | 159 | buildBreakupCellforms(); 160 | 161 | breakup_mode = 0; 162 | if (params[0] == 'l') 163 | breakup_mode |= BREAKUP_MODE_LOWER; 164 | if (params[1] == 'l') 165 | breakup_mode |= BREAKUP_MODE_LEFT; 166 | if ((params[2] >= 'A') && (params[2] <= 'Z')) 167 | breakup_mode |= BREAKUP_MODE_JUMBLE; 168 | if ((params[2] == 'p') || (params[2] == 'P')) 169 | breakup_mode |= BREAKUP_MODE_PILEUP; 170 | 171 | if (!breakup_cells) 172 | breakup_cells = new BreakupCell[BREAKUP_MAX_CELLS]; 173 | buildBreakupMask(); 174 | int n_cell_x = breakup_window.w; 175 | int n_cell_y = breakup_window.h; 176 | int n_cell_diags = n_cell_x + n_cell_y; 177 | n_cells = n_cell_x * n_cell_y; 178 | tot_frames = BREAKUP_MOVE_FRAMES + n_cell_diags + BREAKUP_CELLFORMS - BREAKUP_CELLWIDTH / 2 + 1; 179 | last_frame = 0; 180 | 181 | int n = 0, dir = 1, i = 0, diag_n = 0; 182 | for (i = 0; i < n_cell_x; i++) { 183 | int state = BREAKUP_MOVE_FRAMES + BREAKUP_STILL_STATE + diag_n; 184 | if (breakup_mode & BREAKUP_MODE_PILEUP) 185 | state = 0 - diag_n; 186 | for (int j = i, k = 0; (j >= 0) && (k < n_cell_y); j--, k++) { 187 | breakup_cells[n].cell_x = j + breakup_window.x; 188 | breakup_cells[n].cell_y = k + breakup_window.y; 189 | if (!(breakup_mode & BREAKUP_MODE_LEFT)) 190 | breakup_cells[n].cell_x = breakup_window.x + breakup_window.w - j - 1; 191 | if (breakup_mode & BREAKUP_MODE_LOWER) 192 | breakup_cells[n].cell_y = breakup_window.y + breakup_window.h - k - 1; 193 | breakup_cells[n].dir = dir; 194 | breakup_cells[n].state = state; 195 | breakup_cells[n].radius = 0; 196 | ++dir &= (BREAKUP_DIRECTIONS - 1); 197 | ++n; 198 | } 199 | ++diag_n; 200 | } 201 | for (int i = 1; i < n_cell_y; i++) { 202 | int state = BREAKUP_MOVE_FRAMES + BREAKUP_STILL_STATE + diag_n; 203 | if (breakup_mode & BREAKUP_MODE_PILEUP) 204 | state = 0 - diag_n; 205 | for (int j = n_cell_x - 1, k = i; (k < n_cell_y) && (j >= 0); j--, k++) { 206 | breakup_cells[n].cell_x = j + breakup_window.x; 207 | breakup_cells[n].cell_y = k + breakup_window.y; 208 | if (!(breakup_mode & BREAKUP_MODE_LEFT)) 209 | breakup_cells[n].cell_x = breakup_window.x + n_cell_x - j - 1; 210 | if (breakup_mode & BREAKUP_MODE_LOWER) 211 | breakup_cells[n].cell_y = breakup_window.y + n_cell_y - k - 1; 212 | breakup_cells[n].dir = dir; 213 | breakup_cells[n].state = state; 214 | breakup_cells[n].radius = 0; 215 | ++dir &= (BREAKUP_DIRECTIONS - 1); 216 | ++n; 217 | } 218 | ++diag_n; 219 | } 220 | } 221 | 222 | void ONScripter::effectBreakup(char* params, int duration) 223 | { 224 | while (*params != 0 && *params != '/') params++; 225 | if (*params == '/') params++; 226 | 227 | int x_dir = -1; 228 | int y_dir = -1; 229 | 230 | int frame = tot_frames * effect_counter / duration; 231 | int frame_diff = frame - last_frame; 232 | if (frame_diff == 0) 233 | return; 234 | 235 | SDL_Surface* bg = effect_dst_surface; 236 | SDL_Surface* chr = effect_src_surface; 237 | last_frame += frame_diff; 238 | frame_diff = -frame_diff; 239 | if (breakup_mode & BREAKUP_MODE_PILEUP) { 240 | bg = effect_src_surface; 241 | chr = effect_dst_surface; 242 | frame_diff = -frame_diff; 243 | x_dir = -x_dir; 244 | y_dir = -y_dir; 245 | } 246 | SDL_BlitSurface(bg, NULL, accumulation_surface, NULL); 247 | SDL_Surface* dst = accumulation_surface; 248 | 249 | if (breakup_mode & BREAKUP_MODE_JUMBLE) { 250 | x_dir = -x_dir; 251 | y_dir = -y_dir; 252 | } 253 | if (!(breakup_mode & BREAKUP_MODE_LEFT)) { 254 | x_dir = -x_dir; 255 | } 256 | if (breakup_mode & BREAKUP_MODE_LOWER) { 257 | y_dir = -y_dir; 258 | } 259 | 260 | SDL_LockSurface(chr); 261 | SDL_LockSurface(dst); 262 | ONSBuf* chr_buf = (ONSBuf*)chr->pixels; 263 | ONSBuf* buffer = (ONSBuf*)dst->pixels; 264 | bool* msk_buf = breakup_cellforms; 265 | 266 | for (int n = 0; n < n_cells; ++n) { 267 | SDL_Rect rect; 268 | rect.x = breakup_cells[n].cell_x * BREAKUP_CELLWIDTH; 269 | rect.y = breakup_cells[n].cell_y * BREAKUP_CELLWIDTH; 270 | rect.w = BREAKUP_CELLWIDTH; 271 | rect.h = BREAKUP_CELLWIDTH; 272 | breakup_cells[n].state += frame_diff; 273 | if (breakup_cells[n].state >= (BREAKUP_MOVE_FRAMES + BREAKUP_STILL_STATE)) { 274 | for (int i = 0; i < BREAKUP_CELLWIDTH; ++i) { 275 | for (int j = 0; j < BREAKUP_CELLWIDTH; ++j) { 276 | int x = rect.x + j; 277 | int y = rect.y + i; 278 | if ((x < 0) || (x >= dst->w) || (x >= chr->w) || 279 | (y < 0) || (y >= dst->h) || (y >= chr->h)) 280 | continue; 281 | if (breakup_mask[y * BREAKUP_CELLWIDTH * BREAKUP_MAX_CELL_X + x]) 282 | buffer[y * dst->w + x] = chr_buf[y * chr->w + x]; 283 | } 284 | } 285 | } 286 | else if (breakup_cells[n].state >= BREAKUP_MOVE_FRAMES) { 287 | breakup_cells[n].radius = breakup_cells[n].state - (BREAKUP_MOVE_FRAMES * 3 / 4) + 1; 288 | for (int i = 0; i < BREAKUP_CELLWIDTH; i++) { 289 | for (int j = 0; j < BREAKUP_CELLWIDTH; j++) { 290 | int x = rect.x + j; 291 | int y = rect.y + i; 292 | if ((x < 0) || (x >= dst->w) || (x >= chr->w) || 293 | (y < 0) || (y >= dst->h) || (y >= chr->h)) 294 | continue; 295 | int msk_off = BREAKUP_CELLWIDTH * breakup_cells[n].radius; 296 | if (msk_buf[BREAKUP_CELLWIDTH * BREAKUP_CELLFORMS * i + msk_off + j] && 297 | breakup_mask[y * BREAKUP_CELLWIDTH * BREAKUP_MAX_CELL_X + x]) 298 | buffer[y * dst->w + x] = chr_buf[y * chr->w + x]; 299 | } 300 | } 301 | } 302 | else if (breakup_cells[n].state >= 0) { 303 | int state = breakup_cells[n].state; 304 | int disp_x = x_dir * breakup_disp_x[breakup_cells[n].dir] * (state - BREAKUP_MOVE_FRAMES); 305 | int disp_y = y_dir * breakup_disp_y[breakup_cells[n].dir] * (BREAKUP_MOVE_FRAMES - state); 306 | 307 | breakup_cells[n].radius = 0; 308 | if (breakup_cells[n].state >= (BREAKUP_MOVE_FRAMES / 2)) 309 | breakup_cells[n].radius = (breakup_cells[n].state / 2) - (BREAKUP_MOVE_FRAMES / 4) + 1; 310 | for (int i = 0; i < BREAKUP_CELLWIDTH; i++) { 311 | for (int j = 0; j < BREAKUP_CELLWIDTH; j++) { 312 | int x = disp_x + rect.x + j; 313 | int y = disp_y + rect.y + i; 314 | if ((x < 0) || (x >= dst->w) || 315 | (y < 0) || (y >= dst->h)) 316 | continue; 317 | if (((rect.x + j) < 0) || ((rect.x + j) >= chr->w) || 318 | ((rect.y + i) < 0) || ((rect.y + i) >= chr->h)) 319 | continue; 320 | int msk_off = BREAKUP_CELLWIDTH * breakup_cells[n].radius; 321 | if (msk_buf[BREAKUP_CELLWIDTH * BREAKUP_CELLFORMS * i + msk_off + j] && 322 | breakup_mask[(rect.y + i) * BREAKUP_CELLWIDTH * BREAKUP_MAX_CELL_X + rect.x + j]) 323 | buffer[y * dst->w + x] = 324 | chr_buf[(rect.y + i) * chr->w + rect.x + j]; 325 | } 326 | } 327 | } 328 | } 329 | 330 | SDL_UnlockSurface(accumulation_surface); 331 | SDL_UnlockSurface(chr); 332 | } 333 | -------------------------------------------------------------------------------- /ONScripter_effect_cascade.cpp: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * PonscripterLabel_effect_cascade.cpp 4 | * - Emulation of Takashi Toyama's "cascade.dll" NScripter plugin effect 5 | * 6 | * Copyright (c) 2008-2011 "Uncle" Mion Sonozaki 7 | * 8 | * UncleMion@gmail.com 9 | * 10 | * Copyright (c) 2019-2019 Ogapee 11 | * 12 | * ogapee@aqua.dti2.ne.jp 13 | * 14 | * This program is free software; you can redistribute it and/or modify 15 | * it under the terms of the GNU General Public License as published by 16 | * the Free Software Foundation; either version 2 of the License, or 17 | * (at your option) any later version. 18 | * 19 | * This program is distributed in the hope that it will be useful, 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | * GNU General Public License for more details. 23 | * 24 | * You should have received a copy of the GNU General Public License 25 | * along with this program; if not, see 26 | * or write to the Free Software Foundation, Inc., 27 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 28 | */ 29 | 30 | #include "ONScripter.h" 31 | 32 | void ONScripter::effectCascade(char* params, int duration) 33 | { 34 | enum { 35 | // some constants for cascade 36 | CASCADE_DIR = 1, 37 | CASCADE_LR = 2, 38 | CASCADE_UP = 0, 39 | CASCADE_DOWN = 1, 40 | CASCADE_LEFT = 2, 41 | CASCADE_RIGHT = 3, 42 | CASCADE_CROSS = 4, 43 | CASCADE_IN = 8 44 | }; 45 | 46 | SDL_Surface* src_surface; 47 | SDL_Rect src_rect = screen_rect; 48 | SDL_Rect dst_rect = screen_rect; 49 | int mode, width, start, end; 50 | 51 | while (*params != 0 && *params != '/') params++; 52 | if (*params == '/') params++; 53 | 54 | if (params[0] == 'u') 55 | mode = CASCADE_UP; 56 | else if (params[0] == 'd') 57 | mode = CASCADE_DOWN; 58 | else if (params[0] == 'r') 59 | mode = CASCADE_RIGHT; 60 | else 61 | mode = CASCADE_LEFT; 62 | 63 | if (params[1] == 'i') 64 | mode |= CASCADE_IN; 65 | else if (params[1] == 'x') 66 | mode |= CASCADE_IN | CASCADE_CROSS; 67 | 68 | if (mode & CASCADE_IN) 69 | src_surface = effect_dst_surface; 70 | else 71 | src_surface = effect_src_surface; 72 | 73 | bool dir_flag = false; 74 | if ((!(mode & CASCADE_DIR) && !(mode & CASCADE_IN)) || 75 | ((mode & CASCADE_DIR) && (mode & CASCADE_IN))) 76 | dir_flag = true; 77 | 78 | if (mode & CASCADE_LR) { 79 | // moves left-right 80 | width = screen_width * effect_counter / duration; 81 | if (!(mode & CASCADE_IN)) 82 | width = screen_width - width; 83 | 84 | src_rect.y = dst_rect.y = 0; 85 | src_rect.h = dst_rect.h = screen_height; 86 | src_rect.w = dst_rect.w = 1; 87 | if ((mode & CASCADE_CROSS) && (width > 0)) { 88 | // need to cascade-out the src 89 | if (mode & CASCADE_DIR) { 90 | // moves right 91 | start = 0; 92 | end = width; 93 | dst_rect.x = end; 94 | } 95 | else { 96 | // moves left 97 | start = screen_width - width; 98 | end = screen_width; 99 | dst_rect.x = start; 100 | } 101 | src_rect.x = 0; 102 | SDL_BlitSurface(effect_src_surface, &dst_rect, accumulation_surface, &src_rect); 103 | for (int i = start; i < end; i++) { 104 | dst_rect.x = i; 105 | SDL_BlitSurface(accumulation_surface, &src_rect, effect_src_surface, &dst_rect); 106 | } 107 | } 108 | 109 | if (dir_flag) { 110 | start = width; 111 | end = screen_width; 112 | src_rect.x = start; 113 | } 114 | else { 115 | start = 0; 116 | end = screen_width - width; 117 | src_rect.x = end; 118 | } 119 | for (int i = start; i < end; i++) { 120 | dst_rect.x = i; 121 | SDL_BlitSurface(src_surface, &src_rect, accumulation_surface, &dst_rect); 122 | } 123 | 124 | if (dir_flag) 125 | src_rect.x = 0; 126 | else 127 | src_rect.x = screen_width - width; 128 | dst_rect.x = src_rect.x; 129 | src_rect.w = dst_rect.w = width; 130 | SDL_BlitSurface(src_surface, &src_rect, accumulation_surface, &dst_rect); 131 | } 132 | else { 133 | // moves up-down 134 | width = screen_height * effect_counter / duration; 135 | if (!(mode & CASCADE_IN)) 136 | width = screen_height - width; 137 | 138 | src_rect.x = dst_rect.x = 0; 139 | src_rect.h = dst_rect.h = 1; 140 | src_rect.w = dst_rect.w = screen_width; 141 | if ((mode & CASCADE_CROSS) && (width > 0)) { 142 | // need to cascade-out the src 143 | if (mode & CASCADE_DIR) { 144 | // moves down 145 | start = 0; 146 | end = width; 147 | dst_rect.y = end; 148 | } 149 | else { 150 | // moves up 151 | start = screen_height - width; 152 | end = screen_height; 153 | dst_rect.y = start; 154 | } 155 | src_rect.y = 0; 156 | SDL_BlitSurface(effect_src_surface, &dst_rect, accumulation_surface, &src_rect); 157 | for (int i = start; i < end; i++) { 158 | dst_rect.y = i; 159 | SDL_BlitSurface(accumulation_surface, &src_rect, effect_src_surface, &dst_rect); 160 | } 161 | } 162 | 163 | if (dir_flag) { 164 | start = width; 165 | end = screen_height; 166 | src_rect.y = start; 167 | } 168 | else { 169 | start = 0; 170 | end = screen_height - width; 171 | src_rect.y = end; 172 | } 173 | for (int i = start; i < end; i++) { 174 | dst_rect.y = i; 175 | SDL_BlitSurface(src_surface, &src_rect, accumulation_surface, &dst_rect); 176 | } 177 | 178 | if (dir_flag) 179 | src_rect.y = 0; 180 | else 181 | src_rect.y = screen_height - width; 182 | dst_rect.y = src_rect.y; 183 | src_rect.h = dst_rect.h = width; 184 | SDL_BlitSurface(src_surface, &src_rect, accumulation_surface, &dst_rect); 185 | } 186 | if (mode & CASCADE_CROSS) { 187 | // do crossfade 188 | width = 256 * effect_counter / duration; 189 | SDL_Surface* tmp = effect_dst_surface; 190 | effect_dst_surface = accumulation_surface; 191 | alphaBlend(NULL, ALPHA_BLEND_CONST, width, &dirty_rect.bounding_box); 192 | effect_dst_surface = tmp; 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /ONScripter_file.cpp: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * ONScripter_file.cpp - FILE I/O of ONScripter 4 | * 5 | * Copyright (c) 2001-2018 Ogapee. All rights reserved. 6 | * 7 | * ogapee@aqua.dti2.ne.jp 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #include "ONScripter.h" 25 | 26 | #if defined(LINUX) || defined(MACOSX) || defined(IOS) 27 | #include 28 | #include 29 | #include 30 | #include 31 | #elif defined(WIN32) 32 | #include 33 | extern "C" { 34 | FILE __iob_func[3] = {*stdin, *stdout, *stderr}; 35 | } 36 | #elif defined(MACOS9) 37 | #include 38 | #include 39 | extern "C" void c2pstrcpy(Str255 dst, const char* src); // #include 40 | #elif defined(PSP) 41 | #include 42 | #endif 43 | 44 | #define SAVEFILE_MAGIC_NUMBER "ONS" 45 | #define SAVEFILE_VERSION_MAJOR 2 46 | #define SAVEFILE_VERSION_MINOR 8 47 | 48 | #define READ_LENGTH 4096 49 | 50 | void ONScripter::searchSaveFile(SaveFileInfo& save_file_info, int no) 51 | { 52 | char file_name[256]; 53 | 54 | script_h.getStringFromInteger(save_file_info.sjis_no, no, (num_save_file >= 10) ? 2 : 1); 55 | #if defined(LINUX) || defined(MACOSX) || defined(IOS) 56 | sprintf(file_name, "%ssave%d.dat", save_dir ? save_dir : archive_path, no); 57 | struct stat buf; 58 | struct tm* tm; 59 | if (stat(file_name, &buf) != 0) { 60 | save_file_info.valid = false; 61 | return; 62 | } 63 | time_t mtime = buf.st_mtime; 64 | tm = localtime(&mtime); 65 | 66 | save_file_info.month = tm->tm_mon + 1; 67 | save_file_info.day = tm->tm_mday; 68 | save_file_info.hour = tm->tm_hour; 69 | save_file_info.minute = tm->tm_min; 70 | #elif defined(WIN32) 71 | sprintf(file_name, "%ssave%d.dat", save_dir ? save_dir : archive_path, no); 72 | HANDLE handle; 73 | FILETIME tm, ltm; 74 | SYSTEMTIME stm; 75 | 76 | WCHAR file_nameW[256]; 77 | MultiByteToWideChar(CP_ACP, 0, file_name, -1, file_nameW, 256); 78 | handle = CreateFile(file_nameW, GENERIC_READ, 0, NULL, 79 | OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 80 | if (handle == INVALID_HANDLE_VALUE) { 81 | save_file_info.valid = false; 82 | return; 83 | } 84 | 85 | GetFileTime(handle, NULL, NULL, &tm); 86 | FileTimeToLocalFileTime(&tm, <m); 87 | FileTimeToSystemTime(<m, &stm); 88 | CloseHandle(handle); 89 | 90 | save_file_info.month = stm.wMonth; 91 | save_file_info.day = stm.wDay; 92 | save_file_info.hour = stm.wHour; 93 | save_file_info.minute = stm.wMinute; 94 | #elif defined(MACOS9) 95 | sprintf(file_name, "%ssave%d.dat", save_dir ? save_dir : archive_path, no); 96 | CInfoPBRec pb; 97 | Str255 p_file_name; 98 | FSSpec file_spec; 99 | DateTimeRec tm; 100 | c2pstrcpy(p_file_name, file_name); 101 | if (FSMakeFSSpec(0, 0, p_file_name, &file_spec) != noErr) { 102 | save_file_info.valid = false; 103 | return; 104 | } 105 | pb.hFileInfo.ioNamePtr = file_spec.name; 106 | pb.hFileInfo.ioVRefNum = file_spec.vRefNum; 107 | pb.hFileInfo.ioFDirIndex = 0; 108 | pb.hFileInfo.ioDirID = file_spec.parID; 109 | if (PBGetCatInfoSync(&pb) != noErr) { 110 | save_file_info.valid = false; 111 | return; 112 | } 113 | SecondsToDate(pb.hFileInfo.ioFlMdDat, &tm); 114 | save_file_info.month = tm.month; 115 | save_file_info.day = tm.day; 116 | save_file_info.hour = tm.hour; 117 | save_file_info.minute = tm.minute; 118 | #elif defined(PSP) 119 | sprintf(file_name, "%ssave%d.dat", save_dir ? save_dir : archive_path, no); 120 | SceIoStat buf; 121 | if (sceIoGetstat(file_name, &buf) < 0) { 122 | save_file_info.valid = false; 123 | return; 124 | } 125 | 126 | save_file_info.month = buf.st_mtime.month; 127 | save_file_info.day = buf.st_mtime.day; 128 | save_file_info.hour = buf.st_mtime.hour; 129 | save_file_info.minute = buf.st_mtime.minute; 130 | #else 131 | sprintf(file_name, "save%d.dat", no); 132 | FILE* fp; 133 | if ((fp = fopen(file_name, "rb", true)) == NULL) { 134 | save_file_info.valid = false; 135 | return; 136 | } 137 | fclose(fp); 138 | 139 | save_file_info.month = 1; 140 | save_file_info.day = 1; 141 | save_file_info.hour = 0; 142 | save_file_info.minute = 0; 143 | #endif 144 | save_file_info.valid = true; 145 | script_h.getStringFromInteger(save_file_info.sjis_month, save_file_info.month, 2); 146 | script_h.getStringFromInteger(save_file_info.sjis_day, save_file_info.day, 2); 147 | script_h.getStringFromInteger(save_file_info.sjis_hour, save_file_info.hour, 2); 148 | script_h.getStringFromInteger(save_file_info.sjis_minute, save_file_info.minute, 2, true); 149 | } 150 | 151 | char* ONScripter::readSaveStrFromFile(int no) 152 | { 153 | char filename[32]; 154 | sprintf(filename, "save%d.dat", no); 155 | size_t len = loadFileIOBuf(filename); 156 | if (len == 0) { 157 | fprintf(stderr, "readSaveStrFromFile: can't open save file %s\n", filename); 158 | return NULL; 159 | } 160 | 161 | int p = len - 1; 162 | if (p < 3 || file_io_buf[p] != '*' || file_io_buf[p - 1] != '"') return NULL; 163 | p -= 2; 164 | 165 | while (file_io_buf[p] != '"' && p > 0) p--; 166 | if (file_io_buf[p] != '"') return NULL; 167 | 168 | len = len - p - 3; 169 | char* buf = new char[len + 1]; 170 | 171 | unsigned int i; 172 | for (i = 0; i < len; i++) 173 | buf[i] = file_io_buf[p + i + 1]; 174 | buf[i] = 0; 175 | 176 | return buf; 177 | } 178 | 179 | int ONScripter::loadSaveFile(int no) 180 | { 181 | char filename[32]; 182 | sprintf(filename, "save%d.dat", no); 183 | if (loadFileIOBuf(filename) == 0) { 184 | fprintf(stderr, "can't open save file %s\n", filename); 185 | return -1; 186 | } 187 | 188 | /* ---------------------------------------- */ 189 | /* Load magic number */ 190 | int i; 191 | for (i = 0; i < (int)strlen(SAVEFILE_MAGIC_NUMBER); i++) 192 | if (readChar() != SAVEFILE_MAGIC_NUMBER[i]) break; 193 | 194 | if (i != (int)strlen(SAVEFILE_MAGIC_NUMBER)) { 195 | file_io_buf_ptr = 0; 196 | printf("Save file version is unknown\n"); 197 | return loadSaveFile2(SAVEFILE_VERSION_MAJOR * 100 + SAVEFILE_VERSION_MINOR); 198 | } 199 | 200 | int file_version = readChar() * 100; 201 | file_version += readChar(); 202 | printf("Save file version is %d.%d\n", file_version / 100, file_version % 100); 203 | if (file_version > SAVEFILE_VERSION_MAJOR * 100 + SAVEFILE_VERSION_MINOR) { 204 | fprintf(stderr, "Save file is newer than %d.%d, please use the latest ONScripter.\n", SAVEFILE_VERSION_MAJOR, SAVEFILE_VERSION_MINOR); 205 | return -1; 206 | } 207 | 208 | if (file_version >= 200) 209 | return loadSaveFile2(file_version); 210 | 211 | fprintf(stderr, "Save file is too old.\n"); 212 | 213 | return -1; 214 | } 215 | 216 | void ONScripter::saveMagicNumber(bool output_flag) 217 | { 218 | for (unsigned int i = 0; i < strlen(SAVEFILE_MAGIC_NUMBER); i++) 219 | writeChar(SAVEFILE_MAGIC_NUMBER[i], output_flag); 220 | writeChar(SAVEFILE_VERSION_MAJOR, output_flag); 221 | writeChar(SAVEFILE_VERSION_MINOR, output_flag); 222 | } 223 | 224 | void ONScripter::storeSaveFile() 225 | { 226 | file_io_buf_ptr = 0; 227 | saveMagicNumber(false); 228 | saveSaveFile2(false); 229 | allocFileIOBuf(); 230 | saveMagicNumber(true); 231 | saveSaveFile2(true); 232 | save_data_len = file_io_buf_ptr; 233 | memcpy(save_data_buf, file_io_buf, save_data_len); 234 | } 235 | 236 | int ONScripter::writeSaveFile(int no, const char* savestr) 237 | { 238 | saveAll(); 239 | 240 | char filename[32]; 241 | sprintf(filename, "save%d.dat", no); 242 | 243 | memcpy(file_io_buf, save_data_buf, save_data_len); 244 | file_io_buf_ptr = save_data_len; 245 | if (saveFileIOBuf(filename, 0, savestr)) { 246 | fprintf(stderr, "can't open save file %s for writing\n", filename); 247 | return -1; 248 | } 249 | 250 | size_t magic_len = strlen(SAVEFILE_MAGIC_NUMBER) + 2; 251 | sprintf(filename, RELATIVEPATH "sav%csave%d.dat", DELIMITER, no); 252 | if (saveFileIOBuf(filename, magic_len, savestr)) 253 | fprintf(stderr, "can't open save file %s for writing (not an error)\n", filename); 254 | 255 | return 0; 256 | } 257 | -------------------------------------------------------------------------------- /ONScripter_rmenu.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ogapee/onscripter/848a60892e4d721459e8d1051e1b8fe45164c3e9/ONScripter_rmenu.cpp -------------------------------------------------------------------------------- /ONScripter_sound.cpp: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * ONScripter_sound.cpp - Methods for playing sound 4 | * 5 | * Copyright (c) 2001-2020 Ogapee. All rights reserved. 6 | * 7 | * ogapee@aqua.dti2.ne.jp 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #include "ONScripter.h" 25 | #include 26 | #if defined(LINUX) 27 | #include 28 | #endif 29 | 30 | #ifdef ANDROID 31 | extern "C" void playVideoAndroid(const char* filename); 32 | #endif 33 | 34 | #if defined(IOS) 35 | extern "C" void playVideoIOS(const char* filename, bool click_flag, bool loop_flag); 36 | #endif 37 | 38 | #if defined(USE_AVIFILE) 39 | #include "AVIWrapper.h" 40 | #endif 41 | 42 | #if defined(USE_SMPEG) 43 | extern "C" void mp3callback(void* userdata, Uint8* stream, int len) 44 | { 45 | SMPEG_playAudio((SMPEG*)userdata, stream, len); 46 | } 47 | #endif 48 | 49 | extern bool ext_music_play_once_flag; 50 | 51 | extern "C" { 52 | extern void musicFinishCallback(); 53 | extern Uint32 SDLCALL cdaudioCallback(Uint32 interval, void* param); 54 | } 55 | extern void midiCallback(int sig); 56 | extern SDL_TimerID timer_cdaudio_id; 57 | 58 | extern SDL_TimerID timer_bgmfade_id; 59 | extern "C" Uint32 SDLCALL bgmfadeCallback(Uint32 interval, void* param); 60 | 61 | #define TMP_MUSIC_FILE "tmp.mus" 62 | 63 | int ONScripter::playSound(const char* filename, int format, bool loop_flag, int channel) 64 | { 65 | if (!audio_open_flag) return SOUND_NONE; 66 | 67 | long length = script_h.cBR->getFileLength(filename); 68 | if (length == 0) return SOUND_NONE; 69 | 70 | unsigned char* buffer; 71 | 72 | if (format & SOUND_MUSIC && 73 | length == music_buffer_length && 74 | music_buffer) { 75 | buffer = music_buffer; 76 | } 77 | else { 78 | buffer = new (std::nothrow) unsigned char[length]; 79 | if (buffer == NULL) { 80 | fprintf(stderr, "failed to load [%s] because file size [%lu] is too large.\n", filename, length); 81 | return SOUND_NONE; 82 | } 83 | script_h.cBR->getFile(filename, buffer); 84 | } 85 | 86 | if (format & SOUND_MUSIC) { 87 | music_info = Mix_LoadMUS_RW(SDL_RWFromMem(buffer, length)); 88 | Mix_VolumeMusic(music_volume); 89 | Mix_HookMusicFinished(musicFinishCallback); 90 | if (Mix_PlayMusic(music_info, (music_play_loop_flag && music_loopback_offset == 0.0) ? -1 : 0) == 0) { 91 | music_buffer = buffer; 92 | music_buffer_length = length; 93 | return SOUND_MUSIC; 94 | } 95 | } 96 | 97 | if (format & SOUND_CHUNK) { 98 | Mix_Chunk* chunk = Mix_LoadWAV_RW(SDL_RWFromMem(buffer, length), 1); 99 | if (playWave(chunk, format, loop_flag, channel) == 0) { 100 | delete[] buffer; 101 | return SOUND_CHUNK; 102 | } 103 | } 104 | 105 | /* check WMA */ 106 | if (buffer[0] == 0x30 && buffer[1] == 0x26 && 107 | buffer[2] == 0xb2 && buffer[3] == 0x75) { 108 | delete[] buffer; 109 | return SOUND_OTHER; 110 | } 111 | 112 | if (format & SOUND_MIDI) { 113 | FILE* fp; 114 | if ((fp = fopen(TMP_MUSIC_FILE, "wb", true)) == NULL) { 115 | fprintf(stderr, "can't open temporaly MIDI file %s\n", TMP_MUSIC_FILE); 116 | } 117 | else { 118 | fwrite(buffer, 1, length, fp); 119 | fclose(fp); 120 | ext_music_play_once_flag = !loop_flag; 121 | if (playMIDI(loop_flag) == 0) { 122 | delete[] buffer; 123 | return SOUND_MIDI; 124 | } 125 | } 126 | } 127 | 128 | delete[] buffer; 129 | 130 | return SOUND_OTHER; 131 | } 132 | 133 | void ONScripter::playCDAudio() 134 | { 135 | if (cdaudio_flag) { 136 | #ifdef USE_CDROM 137 | if (cdrom_info) { 138 | int length = cdrom_info->track[current_cd_track - 1].length / 75; 139 | SDL_CDPlayTracks(cdrom_info, current_cd_track - 1, 0, 1, 0); 140 | timer_cdaudio_id = SDL_AddTimer(length * 1000, cdaudioCallback, NULL); 141 | } 142 | #endif 143 | } 144 | else { 145 | char filename[256]; 146 | sprintf(filename, "cd\\track%2.2d.mp3", current_cd_track); 147 | int ret = playSound(filename, SOUND_MUSIC, cd_play_loop_flag); 148 | if (ret == SOUND_MUSIC) return; 149 | 150 | sprintf(filename, "cd\\track%2.2d.ogg", current_cd_track); 151 | ret = playSound(filename, SOUND_MUSIC, cd_play_loop_flag); 152 | if (ret == SOUND_MUSIC) return; 153 | 154 | sprintf(filename, "cd\\track%2.2d.wav", current_cd_track); 155 | ret = playSound(filename, SOUND_MUSIC | SOUND_CHUNK, cd_play_loop_flag, MIX_BGM_CHANNEL); 156 | } 157 | } 158 | 159 | int ONScripter::playWave(Mix_Chunk* chunk, int format, bool loop_flag, int channel) 160 | { 161 | if (!chunk) return -1; 162 | 163 | Mix_Pause(channel); 164 | if (wave_sample[channel]) Mix_FreeChunk(wave_sample[channel]); 165 | wave_sample[channel] = chunk; 166 | 167 | if (channel == 0) 168 | Mix_Volume(channel, voice_volume * MIX_MAX_VOLUME / 100); 169 | else if (channel == MIX_BGM_CHANNEL) 170 | Mix_Volume(channel, music_volume * MIX_MAX_VOLUME / 100); 171 | else 172 | Mix_Volume(channel, se_volume * MIX_MAX_VOLUME / 100); 173 | 174 | if (!(format & SOUND_PRELOAD)) 175 | Mix_PlayChannel(channel, wave_sample[channel], loop_flag ? -1 : 0); 176 | 177 | return 0; 178 | } 179 | 180 | int ONScripter::playMIDI(bool loop_flag) 181 | { 182 | Mix_SetMusicCMD(midi_cmd); 183 | 184 | char midi_filename[256]; 185 | sprintf(midi_filename, "%s%s", save_dir ? save_dir : archive_path, TMP_MUSIC_FILE); 186 | if ((midi_info = Mix_LoadMUS(midi_filename)) == NULL) return -1; 187 | 188 | int midi_looping = loop_flag ? -1 : 0; 189 | 190 | #if defined(LINUX) 191 | signal(SIGCHLD, midiCallback); 192 | if (midi_cmd) midi_looping = 0; 193 | #endif 194 | 195 | Mix_VolumeMusic(music_volume); 196 | Mix_PlayMusic(midi_info, midi_looping); 197 | current_cd_track = -2; 198 | 199 | return 0; 200 | } 201 | 202 | #if defined(USE_SMPEG) 203 | #if defined(USE_SDL_RENDERER) 204 | struct OverlayInfo { 205 | SDL_Overlay overlay; 206 | SDL_mutex* mutex; 207 | }; 208 | static void smpeg_filter_callback(SDL_Overlay* dst, SDL_Overlay* src, SDL_Rect* region, SMPEG_FilterInfo* filter_info, void* data) 209 | { 210 | if (dst) { 211 | dst->w = 0; 212 | dst->h = 0; 213 | } 214 | 215 | OverlayInfo* oi = (OverlayInfo*)data; 216 | 217 | SDL_mutexP(oi->mutex); 218 | memcpy(oi->overlay.pixels[0], src->pixels[0], 219 | oi->overlay.w * oi->overlay.h + (oi->overlay.w / 2) * (oi->overlay.h / 2) * 2); 220 | SDL_mutexV(oi->mutex); 221 | } 222 | static void smpeg_filter_destroy(struct SMPEG_Filter* filter) 223 | { 224 | } 225 | #elif defined(ANDROID) 226 | static void smpeg_filter_callback(SDL_Overlay* dst, SDL_Overlay* src, SDL_Rect* region, SMPEG_FilterInfo* filter_info, void* data) 227 | { 228 | if (dst) { 229 | dst->w = 0; 230 | dst->h = 0; 231 | } 232 | 233 | ONScripter* ons = (ONScripter*)data; 234 | AnimationInfo* ai = ons->getSMPEGInfo(); 235 | ai->convertFromYUV(src); 236 | } 237 | static void smpeg_filter_destroy(struct SMPEG_Filter* filter) 238 | { 239 | } 240 | #endif 241 | #endif 242 | 243 | int ONScripter::playMPEG(const char* filename, bool click_flag, bool loop_flag, bool nosound_flag) 244 | { 245 | unsigned long length = script_h.cBR->getFileLength(filename); 246 | if (length == 0) { 247 | fprintf(stderr, " *** can't find file [%s] ***\n", filename); 248 | return 0; 249 | } 250 | 251 | #ifdef IOS 252 | char* absolute_filename = new char[strlen(archive_path) + strlen(filename) + 1]; 253 | sprintf(absolute_filename, "%s%s", archive_path, filename); 254 | playVideoIOS(absolute_filename, click_flag, loop_flag); 255 | delete[] absolute_filename; 256 | #endif 257 | 258 | int ret = 0; 259 | #if defined(USE_SMPEG) 260 | stopSMPEG(); 261 | layer_smpeg_buffer = new unsigned char[length]; 262 | script_h.cBR->getFile(filename, layer_smpeg_buffer); 263 | SMPEG_Info info; 264 | layer_smpeg_sample = SMPEG_new_rwops(SDL_RWFromMem(layer_smpeg_buffer, length), &info, 0); 265 | unsigned char packet_code[4] = {0x00, 0x00, 0x01, 0xba}; 266 | if (SMPEG_error(layer_smpeg_sample) || 267 | layer_smpeg_buffer[0] != packet_code[0] || 268 | layer_smpeg_buffer[1] != packet_code[1] || 269 | layer_smpeg_buffer[2] != packet_code[2] || 270 | layer_smpeg_buffer[3] != packet_code[3] || 271 | (layer_smpeg_buffer[4] & 0xf0) != 0x20) { 272 | stopSMPEG(); 273 | #ifdef ANDROID 274 | playVideoAndroid(filename); 275 | #endif 276 | return ret; 277 | } 278 | 279 | SMPEG_enableaudio(layer_smpeg_sample, 0); 280 | if (audio_open_flag && !nosound_flag) { 281 | int mpegversion, frequency, layer, bitrate; 282 | char mode[10]; 283 | sscanf(info.audio_string, 284 | "MPEG-%d Layer %d %dkbit/s %dHz %s", 285 | &mpegversion, &layer, &bitrate, &frequency, mode); 286 | printf("MPEG-%d Layer %d %dkbit/s %dHz %s\n", 287 | mpegversion, layer, bitrate, frequency, mode); 288 | 289 | openAudio(frequency); 290 | 291 | SMPEG_actualSpec(layer_smpeg_sample, &audio_format); 292 | SMPEG_enableaudio(layer_smpeg_sample, 1); 293 | } 294 | SMPEG_enablevideo(layer_smpeg_sample, 1); 295 | 296 | #if defined(USE_SDL_RENDERER) 297 | SMPEG_setdisplay(layer_smpeg_sample, accumulation_surface, NULL, NULL); 298 | 299 | OverlayInfo oi; 300 | Uint16 pitches[3]; 301 | Uint8* pixels[3]; 302 | oi.overlay.format = SDL_YV12_OVERLAY; 303 | oi.overlay.w = info.width; 304 | oi.overlay.h = info.height; 305 | oi.overlay.planes = 3; 306 | pitches[0] = info.width; 307 | pitches[1] = info.width / 2; 308 | pitches[2] = info.width / 2; 309 | oi.overlay.pitches = pitches; 310 | Uint8* pixel_buf = new Uint8[info.width * info.height + (info.width / 2) * (info.height / 2) * 2]; 311 | pixels[0] = pixel_buf; 312 | pixels[1] = pixel_buf + info.width * info.height; 313 | pixels[2] = pixel_buf + info.width * info.height + (info.width / 2) * (info.height / 2); 314 | oi.overlay.pixels = pixels; 315 | oi.mutex = SDL_CreateMutex(); 316 | 317 | texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_YV12, SDL_TEXTUREACCESS_TARGET, info.width, info.height); 318 | 319 | layer_smpeg_filter.data = &oi; 320 | layer_smpeg_filter.callback = smpeg_filter_callback; 321 | layer_smpeg_filter.destroy = smpeg_filter_destroy; 322 | SMPEG_filter(layer_smpeg_sample, &layer_smpeg_filter); 323 | #elif defined(ANDROID) 324 | SMPEG_setdisplay(layer_smpeg_sample, screen_surface, NULL, NULL); 325 | AnimationInfo* smpeg_info_back = smpeg_info; 326 | smpeg_info = new AnimationInfo(); 327 | smpeg_info->image_surface = accumulation_surface; 328 | layer_smpeg_filter.data = this; 329 | layer_smpeg_filter.callback = smpeg_filter_callback; 330 | layer_smpeg_filter.destroy = smpeg_filter_destroy; 331 | SMPEG_filter(layer_smpeg_sample, &layer_smpeg_filter); 332 | #else 333 | SMPEG_setdisplay(layer_smpeg_sample, screen_surface, NULL, NULL); 334 | #endif 335 | if (!nosound_flag) { 336 | SMPEG_setvolume(layer_smpeg_sample, music_volume); 337 | if (info.has_audio) Mix_HookMusic(mp3callback, layer_smpeg_sample); 338 | } 339 | 340 | SMPEG_loop(layer_smpeg_sample, loop_flag ? 1 : 0); 341 | SMPEG_play(layer_smpeg_sample); 342 | 343 | bool done_flag = false; 344 | while (!(done_flag & click_flag) && SMPEG_status(layer_smpeg_sample) == SMPEG_PLAYING) { 345 | SDL_Event event; 346 | 347 | while (SDL_PollEvent(&event)) { 348 | switch (event.type) { 349 | case SDL_KEYUP: 350 | if (((SDL_KeyboardEvent*)&event)->keysym.sym == SDLK_RETURN || 351 | ((SDL_KeyboardEvent*)&event)->keysym.sym == SDLK_SPACE || 352 | ((SDL_KeyboardEvent*)&event)->keysym.sym == SDLK_ESCAPE) 353 | done_flag = true; 354 | if (((SDL_KeyboardEvent*)&event)->keysym.sym == SDLK_RCTRL) 355 | ctrl_pressed_status &= ~0x01; 356 | 357 | if (((SDL_KeyboardEvent*)&event)->keysym.sym == SDLK_LCTRL) 358 | ctrl_pressed_status &= ~0x02; 359 | break; 360 | case SDL_QUIT: 361 | ret = 1; 362 | case SDL_MOUSEBUTTONUP: 363 | done_flag = true; 364 | break; 365 | default: 366 | break; 367 | } 368 | } 369 | 370 | #if defined(USE_SDL_RENDERER) 371 | SDL_mutexP(oi.mutex); 372 | flushDirectYUV(&oi.overlay); 373 | SDL_mutexV(oi.mutex); 374 | #elif defined(ANDROID) 375 | SDL_mutexP(smpeg_info->mutex); 376 | flushDirect(screen_rect, REFRESH_NONE_MODE); 377 | SDL_mutexV(smpeg_info->mutex); 378 | #endif 379 | SDL_Delay(1); 380 | } 381 | 382 | if (!nosound_flag) 383 | Mix_HookMusic(NULL, NULL); 384 | stopSMPEG(); 385 | if (!nosound_flag) 386 | openAudio(); 387 | #if defined(USE_SDL_RENDERER) 388 | delete[] pixel_buf; 389 | SDL_DestroyMutex(oi.mutex); 390 | texture = SDL_CreateTextureFromSurface(renderer, accumulation_surface); 391 | #elif defined(ANDROID) 392 | smpeg_info->image_surface = NULL; 393 | delete smpeg_info; 394 | smpeg_info = smpeg_info_back; 395 | #endif 396 | #elif !defined(IOS) 397 | fprintf(stderr, "mpegplay command is disabled.\n"); 398 | #endif 399 | 400 | return ret; 401 | } 402 | 403 | int ONScripter::playAVI(const char* filename, bool click_flag) 404 | { 405 | unsigned long length = script_h.cBR->getFileLength(filename); 406 | if (length == 0) { 407 | fprintf(stderr, " *** can't find file [%s] ***\n", filename); 408 | return 0; 409 | } 410 | 411 | #ifdef ANDROID 412 | playVideoAndroid(filename); 413 | return 0; 414 | #endif 415 | 416 | #if defined(USE_AVIFILE) && !defined(USE_SDL_RENDERER) 417 | char* absolute_filename = new char[strlen(archive_path) + strlen(filename) + 1]; 418 | sprintf(absolute_filename, "%s%s", archive_path, filename); 419 | for (unsigned int i = 0; i < strlen(absolute_filename); i++) 420 | if (absolute_filename[i] == '/' || 421 | absolute_filename[i] == '\\') 422 | absolute_filename[i] = DELIMITER; 423 | 424 | if (audio_open_flag) Mix_CloseAudio(); 425 | 426 | AVIWrapper* avi = new AVIWrapper(); 427 | if (avi->init(absolute_filename, false) == 0 && 428 | avi->initAV(screen_surface, audio_open_flag) == 0) { 429 | if (avi->play(click_flag)) return 1; 430 | } 431 | delete avi; 432 | delete[] absolute_filename; 433 | 434 | if (audio_open_flag) { 435 | Mix_CloseAudio(); 436 | openAudio(); 437 | } 438 | #else 439 | fprintf(stderr, "avi command is disabled.\n"); 440 | #endif 441 | 442 | return 0; 443 | } 444 | 445 | void ONScripter::stopBGM(bool continue_flag) 446 | { 447 | removeBGMFadeEvent(); 448 | if (timer_bgmfade_id) SDL_RemoveTimer(timer_bgmfade_id); 449 | timer_bgmfade_id = NULL; 450 | mp3fadeout_duration_internal = 0; 451 | 452 | #ifdef USE_CDROM 453 | if (cdaudio_flag && cdrom_info) { 454 | extern SDL_TimerID timer_cdaudio_id; 455 | 456 | if (timer_cdaudio_id) { 457 | SDL_RemoveTimer(timer_cdaudio_id); 458 | timer_cdaudio_id = NULL; 459 | } 460 | if (SDL_CDStatus(cdrom_info) >= CD_PLAYING) 461 | SDL_CDStop(cdrom_info); 462 | } 463 | #endif 464 | 465 | if (wave_sample[MIX_BGM_CHANNEL]) { 466 | Mix_Pause(MIX_BGM_CHANNEL); 467 | Mix_FreeChunk(wave_sample[MIX_BGM_CHANNEL]); 468 | wave_sample[MIX_BGM_CHANNEL] = NULL; 469 | } 470 | 471 | if (music_info) { 472 | ext_music_play_once_flag = true; 473 | Mix_HaltMusic(); 474 | Mix_FreeMusic(music_info); 475 | music_info = NULL; 476 | } 477 | 478 | if (midi_info) { 479 | ext_music_play_once_flag = true; 480 | Mix_HaltMusic(); 481 | Mix_FreeMusic(midi_info); 482 | midi_info = NULL; 483 | } 484 | 485 | if (!continue_flag) { 486 | setStr(&music_file_name, NULL); 487 | music_play_loop_flag = false; 488 | if (music_buffer) { 489 | delete[] music_buffer; 490 | music_buffer = NULL; 491 | } 492 | 493 | setStr(&midi_file_name, NULL); 494 | midi_play_loop_flag = false; 495 | 496 | current_cd_track = -1; 497 | } 498 | } 499 | 500 | void ONScripter::stopAllDWAVE() 501 | { 502 | for (int ch = 0; ch < ONS_MIX_CHANNELS; ch++) 503 | if (wave_sample[ch]) { 504 | Mix_Pause(ch); 505 | Mix_FreeChunk(wave_sample[ch]); 506 | wave_sample[ch] = NULL; 507 | } 508 | } 509 | 510 | void ONScripter::playClickVoice() 511 | { 512 | if (clickstr_state == CLICK_NEWPAGE) { 513 | if (clickvoice_file_name[CLICKVOICE_NEWPAGE]) 514 | playSound(clickvoice_file_name[CLICKVOICE_NEWPAGE], 515 | SOUND_CHUNK, false, MIX_WAVE_CHANNEL); 516 | } 517 | else if (clickstr_state == CLICK_WAIT) { 518 | if (clickvoice_file_name[CLICKVOICE_NORMAL]) 519 | playSound(clickvoice_file_name[CLICKVOICE_NORMAL], 520 | SOUND_CHUNK, false, MIX_WAVE_CHANNEL); 521 | } 522 | } 523 | -------------------------------------------------------------------------------- /ONScripter_text.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ogapee/onscripter/848a60892e4d721459e8d1051e1b8fe45164c3e9/ONScripter_text.cpp -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ogapee/onscripter/848a60892e4d721459e8d1051e1b8fe45164c3e9/README -------------------------------------------------------------------------------- /SarReader.cpp: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * SarReader.cpp - Reader from a SAR archive 4 | * 5 | * Copyright (c) 2001-2014 Ogapee. All rights reserved. 6 | * 7 | * ogapee@aqua.dti2.ne.jp 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #include "SarReader.h" 25 | #define WRITE_LENGTH 4096 26 | 27 | #if defined(PSP) 28 | extern int psp_power_resume_number; 29 | #endif 30 | 31 | SarReader::SarReader(const char* path, const unsigned char* key_table) 32 | : DirectReader(path, key_table) 33 | { 34 | root_archive_info = last_archive_info = &archive_info; 35 | num_of_sar_archives = 0; 36 | } 37 | 38 | SarReader::~SarReader() 39 | { 40 | close(); 41 | } 42 | 43 | int SarReader::open(const char* name) 44 | { 45 | ArchiveInfo* info = new ArchiveInfo(); 46 | 47 | if ((info->file_handle = fopen(name, "rb")) == NULL) { 48 | delete info; 49 | return -1; 50 | } 51 | 52 | info->file_name = new char[strlen(name) + 1]; 53 | memcpy(info->file_name, name, strlen(name) + 1); 54 | 55 | readArchive(info); 56 | 57 | last_archive_info->next = info; 58 | last_archive_info = last_archive_info->next; 59 | num_of_sar_archives++; 60 | 61 | return 0; 62 | } 63 | 64 | void SarReader::readArchive(ArchiveInfo* ai, int archive_type, unsigned int offset) 65 | { 66 | unsigned int i; 67 | 68 | /* Read header */ 69 | for (i = 0; i < offset; i++) 70 | readChar(ai->file_handle); // for commands "ns2" and "ns3" 71 | 72 | if (archive_type == ARCHIVE_TYPE_NS2) { 73 | // new archive type since NScr2.91 74 | // - header starts with base_offset (byte-swapped), followed by 75 | // filename data - doesn't tell how many files! 76 | // - filenames are surrounded by ""s 77 | // - new NS2 filename def: "filename", length (4bytes, swapped) 78 | // - no compression type? really, no compression. 79 | // - not sure if NS2 uses key_table or not, using default funcs for now 80 | ai->base_offset = swapLong(readLong(ai->file_handle)); 81 | ai->base_offset += offset; 82 | 83 | // need to parse the whole header to see how many files there are 84 | ai->num_of_files = 0; 85 | long unsigned int cur_offset = offset + 4; 86 | // there's an extra byte at the end of the header, not sure what for 87 | while (1) { 88 | unsigned char ch = key_table[fgetc(ai->file_handle)]; 89 | if (ch != '"') break; 90 | cur_offset++; 91 | do cur_offset++; 92 | while ((ch = key_table[fgetc(ai->file_handle)]) != '"'); 93 | cur_offset += 4; 94 | readLong(ai->file_handle); 95 | ai->num_of_files++; 96 | } 97 | ai->fi_list = new FileInfo[ai->num_of_files]; 98 | 99 | // now go back to the beginning and read the file info 100 | cur_offset = ai->base_offset; 101 | fseek(ai->file_handle, 4 + offset, SEEK_SET); 102 | for (i = 0; i < ai->num_of_files; i++) { 103 | unsigned int count = 0; 104 | // skip the beginning double-quote 105 | unsigned char ch = key_table[fgetc(ai->file_handle)]; 106 | while ((ch = key_table[fgetc(ai->file_handle)]) != '"') { 107 | if ('a' <= ch && ch <= 'z') ch += 'A' - 'a'; 108 | ai->fi_list[i].name[count++] = ch; 109 | } 110 | ai->fi_list[i].name[count] = '\0'; 111 | ai->fi_list[i].compression_type = getRegisteredCompressionType(ai->fi_list[i].name); 112 | ai->fi_list[i].offset = cur_offset; 113 | ai->fi_list[i].length = swapLong(readLong(ai->file_handle)); 114 | ai->fi_list[i].original_length = ai->fi_list[i].length; 115 | cur_offset += ai->fi_list[i].length; 116 | } 117 | } 118 | else { 119 | // old NSA filename def: filename, ending '\0' byte , compr-type byte, 120 | // start (4byte), length (4byte)) 121 | ai->num_of_files = readShort(ai->file_handle); 122 | ai->fi_list = new FileInfo[ai->num_of_files]; 123 | 124 | ai->base_offset = readLong(ai->file_handle); 125 | ai->base_offset += offset; 126 | 127 | for (i = 0; i < ai->num_of_files; i++) { 128 | unsigned char ch; 129 | int count = 0; 130 | 131 | while ((ch = key_table[fgetc(ai->file_handle)])) { 132 | if ('a' <= ch && ch <= 'z') ch += 'A' - 'a'; 133 | ai->fi_list[i].name[count++] = ch; 134 | } 135 | ai->fi_list[i].name[count] = ch; 136 | 137 | if (archive_type == ARCHIVE_TYPE_NSA) 138 | ai->fi_list[i].compression_type = readChar(ai->file_handle); 139 | else 140 | ai->fi_list[i].compression_type = NO_COMPRESSION; 141 | ai->fi_list[i].offset = readLong(ai->file_handle) + ai->base_offset; 142 | ai->fi_list[i].length = readLong(ai->file_handle); 143 | 144 | if (archive_type == ARCHIVE_TYPE_NSA) { 145 | ai->fi_list[i].original_length = readLong(ai->file_handle); 146 | } 147 | else { 148 | ai->fi_list[i].original_length = ai->fi_list[i].length; 149 | } 150 | 151 | /* Registered Plugin check */ 152 | if (ai->fi_list[i].compression_type == NO_COMPRESSION) 153 | ai->fi_list[i].compression_type = getRegisteredCompressionType(ai->fi_list[i].name); 154 | 155 | if (ai->fi_list[i].compression_type == NBZ_COMPRESSION || 156 | ai->fi_list[i].compression_type == SPB_COMPRESSION) { 157 | // Delaying checking decompressed file length to prevent 158 | // massive random access in the archives at the start-up. 159 | ai->fi_list[i].original_length = 0; 160 | } 161 | } 162 | } 163 | } 164 | 165 | int SarReader::writeHeaderSub(ArchiveInfo* ai, FILE* fp, int archive_type, int nsa_offset) 166 | { 167 | unsigned int i, j; 168 | 169 | fseek(fp, 0L, SEEK_SET); 170 | for (int k = 0; k < nsa_offset; k++) 171 | fputc(0, fp); 172 | writeShort(fp, ai->num_of_files); 173 | writeLong(fp, ai->base_offset - nsa_offset); 174 | 175 | for (i = 0; i < ai->num_of_files; i++) { 176 | for (j = 0; ai->fi_list[i].name[j]; j++) 177 | fputc(ai->fi_list[i].name[j], fp); 178 | fputc(ai->fi_list[i].name[j], fp); 179 | 180 | if (archive_type >= ARCHIVE_TYPE_NSA) 181 | writeChar(fp, ai->fi_list[i].compression_type); 182 | 183 | writeLong(fp, ai->fi_list[i].offset - ai->base_offset); 184 | writeLong(fp, ai->fi_list[i].length); 185 | 186 | if (archive_type >= ARCHIVE_TYPE_NSA) { 187 | writeLong(fp, ai->fi_list[i].original_length); 188 | } 189 | } 190 | 191 | return 0; 192 | } 193 | 194 | int SarReader::writeHeader(FILE* fp) 195 | { 196 | ArchiveInfo* ai = archive_info.next; 197 | return writeHeaderSub(ai, fp); 198 | } 199 | 200 | size_t SarReader::putFileSub(ArchiveInfo* ai, FILE* fp, int no, size_t offset, size_t length, size_t original_length, int compression_type, bool modified_flag, unsigned char* buffer) 201 | { 202 | ai->fi_list[no].compression_type = compression_type; 203 | ai->fi_list[no].length = length; 204 | ai->fi_list[no].original_length = original_length; 205 | 206 | fseek(fp, offset, SEEK_SET); 207 | if (modified_flag) { 208 | if (ai->fi_list[no].compression_type == NBZ_COMPRESSION) { 209 | writeLong(fp, ai->fi_list[no].original_length); 210 | fseek(ai->file_handle, ai->fi_list[no].offset + 2, SEEK_SET); 211 | if (readChar(ai->file_handle) != 'B' || readChar(ai->file_handle) != 'Z') { // in case the original is not compressed in NBZ 212 | ai->fi_list[no].length = encodeNBZ(fp, length, buffer) + 4; 213 | ai->fi_list[no].offset = offset; 214 | return ai->fi_list[no].length; 215 | } 216 | } 217 | else { 218 | ai->fi_list[no].compression_type = NO_COMPRESSION; 219 | } 220 | } 221 | else { 222 | fseek(ai->file_handle, ai->fi_list[no].offset, SEEK_SET); 223 | fread(buffer, 1, ai->fi_list[no].length, ai->file_handle); 224 | } 225 | 226 | size_t len = ai->fi_list[no].length, c; 227 | while (len > 0) { 228 | if (len > WRITE_LENGTH) 229 | c = WRITE_LENGTH; 230 | else 231 | c = len; 232 | len -= c; 233 | fwrite(buffer, 1, c, fp); 234 | buffer += c; 235 | } 236 | 237 | ai->fi_list[no].offset = offset; 238 | 239 | return ai->fi_list[no].length; 240 | } 241 | 242 | size_t SarReader::putFile(FILE* fp, int no, size_t offset, size_t length, size_t original_length, bool modified_flag, unsigned char* buffer) 243 | { 244 | ArchiveInfo* ai = archive_info.next; 245 | return putFileSub(ai, fp, no, offset, length, original_length, ai->fi_list[no].compression_type, modified_flag, buffer); 246 | } 247 | 248 | int SarReader::close() 249 | { 250 | ArchiveInfo* info = archive_info.next; 251 | 252 | for (int i = 0; i < num_of_sar_archives; i++) { 253 | last_archive_info = info; 254 | info = info->next; 255 | delete last_archive_info; 256 | } 257 | return 0; 258 | } 259 | 260 | const char* SarReader::getArchiveName() const 261 | { 262 | return "sar"; 263 | } 264 | 265 | int SarReader::getNumFiles() 266 | { 267 | ArchiveInfo* info = archive_info.next; 268 | int num = 0; 269 | 270 | for (int i = 0; i < num_of_sar_archives; i++) { 271 | num += info->num_of_files; 272 | info = info->next; 273 | } 274 | 275 | return num; 276 | } 277 | 278 | int SarReader::getIndexFromFile(ArchiveInfo* ai, const char* file_name) 279 | { 280 | unsigned int i, len; 281 | 282 | len = strlen(file_name); 283 | if (len > MAX_FILE_NAME_LENGTH) len = MAX_FILE_NAME_LENGTH; 284 | memcpy(capital_name, file_name, len); 285 | capital_name[len] = '\0'; 286 | 287 | for (i = 0; i < len; i++) { 288 | if ('a' <= capital_name[i] && capital_name[i] <= 'z') 289 | capital_name[i] += 'A' - 'a'; 290 | else if (capital_name[i] == '/') 291 | capital_name[i] = '\\'; 292 | } 293 | for (i = 0; i < ai->num_of_files; i++) { 294 | if (!strcmp(capital_name, ai->fi_list[i].name)) break; 295 | } 296 | 297 | return i; 298 | } 299 | 300 | size_t SarReader::getFileLength(const char* file_name) 301 | { 302 | size_t ret; 303 | if ((ret = DirectReader::getFileLength(file_name))) return ret; 304 | 305 | ArchiveInfo* info = archive_info.next; 306 | unsigned int j = 0; 307 | for (int i = 0; i < num_of_sar_archives; i++) { 308 | j = getIndexFromFile(info, file_name); 309 | if (j != info->num_of_files) break; 310 | info = info->next; 311 | } 312 | if (!info) return 0; 313 | 314 | if (info->fi_list[j].original_length != 0) 315 | return info->fi_list[j].original_length; 316 | 317 | int type = info->fi_list[j].compression_type; 318 | if (type == NO_COMPRESSION) 319 | type = getRegisteredCompressionType(file_name); 320 | if (type == NBZ_COMPRESSION || type == SPB_COMPRESSION) { 321 | info->fi_list[j].original_length = getDecompressedFileLength(type, info->file_handle, info->fi_list[j].offset); 322 | } 323 | 324 | return info->fi_list[j].original_length; 325 | } 326 | 327 | size_t SarReader::getFileSub(ArchiveInfo* ai, const char* file_name, unsigned char* buf) 328 | { 329 | unsigned int i = getIndexFromFile(ai, file_name); 330 | if (i == ai->num_of_files) return 0; 331 | 332 | #if defined(PSP) 333 | if (ai->power_resume_number != psp_power_resume_number) { 334 | FILE* fp = fopen(ai->file_name, "rb"); 335 | ai->file_handle = fp; 336 | ai->power_resume_number = psp_power_resume_number; 337 | } 338 | #endif 339 | 340 | int type = ai->fi_list[i].compression_type; 341 | if (type == NO_COMPRESSION) type = getRegisteredCompressionType(file_name); 342 | 343 | if (type == NBZ_COMPRESSION) { 344 | return decodeNBZ(ai->file_handle, ai->fi_list[i].offset, buf); 345 | } 346 | else if (type == LZSS_COMPRESSION) { 347 | return decodeLZSS(ai, i, buf); 348 | } 349 | else if (type == SPB_COMPRESSION) { 350 | return decodeSPB(ai->file_handle, ai->fi_list[i].offset, buf); 351 | } 352 | 353 | fseek(ai->file_handle, ai->fi_list[i].offset, SEEK_SET); 354 | size_t ret = fread(buf, 1, ai->fi_list[i].length, ai->file_handle); 355 | if (key_table_flag) 356 | for (size_t j = 0; j < ret; j++) buf[j] = key_table[buf[j]]; 357 | return ret; 358 | } 359 | 360 | size_t SarReader::getFile(const char* file_name, unsigned char* buf, int* location) 361 | { 362 | size_t ret; 363 | if ((ret = DirectReader::getFile(file_name, buf, location))) return ret; 364 | 365 | ArchiveInfo* info = archive_info.next; 366 | size_t j = 0; 367 | for (int i = 0; i < num_of_sar_archives; i++) { 368 | if ((j = getFileSub(info, file_name, buf)) > 0) break; 369 | info = info->next; 370 | } 371 | if (location) *location = ARCHIVE_TYPE_SAR; 372 | 373 | return j; 374 | } 375 | 376 | SarReader::FileInfo SarReader::getFileByIndex(unsigned int index) 377 | { 378 | ArchiveInfo* info = archive_info.next; 379 | for (int i = 0; i < num_of_sar_archives; i++) { 380 | if (index < info->num_of_files) return info->fi_list[index]; 381 | index -= info->num_of_files; 382 | info = info->next; 383 | } 384 | fprintf(stderr, "SarReader::getFileByIndex Index %d is out of range\n", index); 385 | 386 | return archive_info.fi_list[index]; 387 | } 388 | -------------------------------------------------------------------------------- /SarReader.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * SarReader.h - Reader from a SAR archive 4 | * 5 | * Copyright (c) 2001-2014 Ogapee. All rights reserved. 6 | * 7 | * ogapee@aqua.dti2.ne.jp 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #ifndef __SAR_READER_H__ 25 | #define __SAR_READER_H__ 26 | 27 | #include "DirectReader.h" 28 | 29 | class SarReader : public DirectReader { 30 | public: 31 | SarReader(const char* path = NULL, const unsigned char* key_table = NULL); 32 | ~SarReader(); 33 | 34 | int open(const char* name = NULL); 35 | int close(); 36 | const char* getArchiveName() const; 37 | int getNumFiles(); 38 | 39 | size_t getFileLength(const char* file_name); 40 | size_t getFile(const char* file_name, unsigned char* buf, int* location = NULL); 41 | FileInfo getFileByIndex(unsigned int index); 42 | 43 | int writeHeader(FILE* fp); 44 | size_t putFile(FILE* fp, int no, size_t offset, size_t length, size_t original_length, bool modified_flag, unsigned char* buffer); 45 | 46 | protected: 47 | ArchiveInfo archive_info; 48 | ArchiveInfo *root_archive_info, *last_archive_info; 49 | int num_of_sar_archives; 50 | 51 | void readArchive(ArchiveInfo* ai, int archive_type = ARCHIVE_TYPE_SAR, unsigned int offset = 0); 52 | int readArchiveSub(ArchiveInfo* ai, int archive_type = ARCHIVE_TYPE_SAR, bool check_size = true); 53 | int getIndexFromFile(ArchiveInfo* ai, const char* file_name); 54 | size_t getFileSub(ArchiveInfo* ai, const char* file_name, unsigned char* buf); 55 | 56 | int writeHeaderSub(ArchiveInfo* ai, FILE* fp, int archive_type = ARCHIVE_TYPE_SAR, int nsa_offset = 0); 57 | size_t putFileSub(ArchiveInfo* ai, FILE* fp, int no, size_t offset, size_t length, size_t original_length, int compression_type, bool modified_flag, unsigned char* buffer); 58 | }; 59 | 60 | #endif // __SAR_READER_H__ 61 | -------------------------------------------------------------------------------- /ScriptHandler.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ogapee/onscripter/848a60892e4d721459e8d1051e1b8fe45164c3e9/ScriptHandler.cpp -------------------------------------------------------------------------------- /ScriptHandler.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * ScriptHandler.h - Script manipulation class 4 | * 5 | * Copyright (c) 2001-2020 Ogapee. All rights reserved. 6 | * 7 | * ogapee@aqua.dti2.ne.jp 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #ifndef __SCRIPT_HANDLER_H__ 25 | #define __SCRIPT_HANDLER_H__ 26 | 27 | #include 28 | #include 29 | #include 30 | #include "BaseReader.h" 31 | #include "Encoding.h" 32 | 33 | #define IS_TWO_BYTE(x) \ 34 | (((x)&0xe0) == 0xe0 || ((x)&0xe0) == 0x80) 35 | 36 | typedef unsigned char uchar3[3]; 37 | 38 | class ScriptHandler { 39 | public: 40 | enum { END_NONE = 0, 41 | END_COMMA = 1, 42 | END_1BYTE_CHAR = 2, 43 | END_COMMA_READ = 4 // for LUA 44 | }; 45 | struct LabelInfo { 46 | char* name; 47 | char* label_header; 48 | char* start_address; 49 | int start_line; 50 | int num_of_lines; 51 | }; 52 | 53 | struct ArrayVariable { 54 | struct ArrayVariable* next; 55 | int no; 56 | int num_dim; 57 | int dim[20]; 58 | int* data; 59 | ArrayVariable() 60 | { 61 | next = NULL; 62 | data = NULL; 63 | }; 64 | ~ArrayVariable() 65 | { 66 | if (data) delete[] data; 67 | }; 68 | ArrayVariable& operator=(const ArrayVariable& av) 69 | { 70 | no = av.no; 71 | num_dim = av.num_dim; 72 | 73 | int total_dim = 1; 74 | for (int i = 0; i < 20; i++) { 75 | dim[i] = av.dim[i]; 76 | total_dim *= dim[i]; 77 | } 78 | 79 | if (data) delete[] data; 80 | data = NULL; 81 | if (av.data) { 82 | data = new int[total_dim]; 83 | memcpy(data, av.data, sizeof(int) * total_dim); 84 | } 85 | 86 | return *this; 87 | }; 88 | }; 89 | 90 | enum { VAR_NONE = 0, 91 | VAR_INT = 1, // integer 92 | VAR_ARRAY = 2, // array 93 | VAR_STR = 4, // string 94 | VAR_CONST = 8, // direct value or alias, not variable 95 | VAR_PTR = 16 // pointer to a variable, e.g. i%0, s%0 96 | }; 97 | struct VariableInfo { 98 | int type; 99 | int var_no; // for integer(%), array(?), string($) variable 100 | ArrayVariable array; // for array(?) 101 | }; 102 | 103 | ScriptHandler(); 104 | ~ScriptHandler(); 105 | 106 | void reset(); 107 | void setSaveDir(const char* path); 108 | FILE* fopen(const char* path, const char* mode, bool use_save_dir = false); 109 | void setKeyTable(const unsigned char* key_table); 110 | 111 | // basic parser function 112 | const char* readToken(); 113 | const char* readLabel(); 114 | const char* readStr(); 115 | int readInt(); 116 | void skipToken(); 117 | int parseInt(char** buf); 118 | int parseIntExpression(char** buf); 119 | void readVariable(bool reread_flag = false); 120 | 121 | // function for string access 122 | inline char* getStringBuffer() { return string_buffer; }; 123 | char* saveStringBuffer(); 124 | void addStringBuffer(char ch); 125 | 126 | // function for direct manipulation of script address 127 | inline char* getCurrent(bool use_script = false) { return (use_script && !is_internal_script) ? last_script_context->current_script : current_script; }; 128 | inline char* getNext() { return next_script; }; 129 | inline char* getWait() { return wait_script ? wait_script : next_script; }; 130 | void setCurrent(char* pos); 131 | void pushCurrent(char* pos); 132 | void popCurrent(); 133 | 134 | void enterExternalScript(char* pos); // LUA 135 | void leaveExternalScript(); 136 | bool isExternalScript(); 137 | 138 | int getOffset(char* pos); 139 | char* getAddress(int offset); 140 | int getLineByAddress(char* address); 141 | char* getAddressByLine(int line); 142 | LabelInfo getLabelByAddress(char* address); 143 | LabelInfo getLabelByLine(int line); 144 | 145 | bool isName(const char* name); 146 | bool isText(); 147 | bool compareString(const char* buf); 148 | void setEndStatus(int val, bool replace = false) 149 | { 150 | if (replace) 151 | end_status = val; 152 | else 153 | end_status |= val; 154 | }; 155 | inline int getEndStatus() { return end_status; }; 156 | void skipLine(int no = 1); 157 | void setLinepage(bool val); 158 | void setEnglishMode(bool val) { english_mode = val; }; 159 | 160 | // function for kidoku history 161 | bool isKidoku(); 162 | void markAsKidoku(char* address = NULL); 163 | void setKidokuskip(bool kidokuskip_flag); 164 | void saveKidokuData(); 165 | void loadKidokuData(); 166 | 167 | void addStrVariable(char** buf); 168 | void addIntVariable(char** buf); 169 | void declareDim(); 170 | 171 | void setClickstr(const char* list); 172 | int checkClickstr(const char* buf, bool recursive_flag = false); 173 | 174 | void setInt(VariableInfo* var_info, int val, int offset = 0); 175 | void setNumVariable(int no, int val); 176 | void pushVariable(); 177 | int getIntVariable(VariableInfo* var_info = NULL); 178 | 179 | int getStringFromInteger(char* buffer, int no, int num_column, bool is_zero_inserted = false); 180 | 181 | int openScript(char* path); 182 | 183 | LabelInfo lookupLabel(const char* label); 184 | LabelInfo lookupLabelNext(const char* label); 185 | void errorAndExit(const char* str); 186 | 187 | ArrayVariable* getRootArrayVariable(); 188 | void loadArrayVariable(FILE* fp); 189 | 190 | void addNumAlias(const char* str, int no); 191 | void addStrAlias(const char* str1, const char* str2); 192 | 193 | enum { LABEL_LOG = 0, 194 | FILE_LOG = 1 195 | }; 196 | struct LogLink { 197 | LogLink* next; 198 | char* name; 199 | 200 | LogLink() 201 | { 202 | next = NULL; 203 | name = NULL; 204 | }; 205 | ~LogLink() 206 | { 207 | if (name) delete[] name; 208 | }; 209 | }; 210 | struct LogInfo { 211 | LogLink root_log; 212 | LogLink* current_log; 213 | int num_logs; 214 | const char* filename; 215 | } log_info[2]; 216 | LogLink* findAndAddLog(LogInfo& info, const char* name, bool add_flag); 217 | void resetLog(LogInfo& info); 218 | 219 | /* ---------------------------------------- */ 220 | /* Variable */ 221 | struct VariableData { 222 | int num; 223 | bool num_limit_flag; 224 | int num_limit_upper; 225 | int num_limit_lower; 226 | char* str; 227 | 228 | VariableData() 229 | { 230 | str = NULL; 231 | reset(true); 232 | }; 233 | void reset(bool limit_reset_flag) 234 | { 235 | num = 0; 236 | if (limit_reset_flag) 237 | num_limit_flag = false; 238 | if (str) { 239 | delete[] str; 240 | str = NULL; 241 | } 242 | }; 243 | }; 244 | VariableData& getVariableData(int no); 245 | 246 | VariableInfo current_variable, pushed_variable; 247 | 248 | int screen_width; 249 | int screen_height; 250 | int variable_range; 251 | int global_variable_border; 252 | int current_language; 253 | 254 | BaseReader* cBR; 255 | Encoding enc; 256 | 257 | private: 258 | enum { OP_INVALID = 0, // 000 259 | OP_PLUS = 2, // 010 260 | OP_MINUS = 3, // 011 261 | OP_MULT = 4, // 100 262 | OP_DIV = 5, // 101 263 | OP_MOD = 6 // 110 264 | }; 265 | 266 | struct Alias { 267 | struct Alias* next; 268 | char* alias; 269 | int num; 270 | char* str; 271 | 272 | Alias() 273 | { 274 | next = NULL; 275 | alias = NULL; 276 | str = NULL; 277 | }; 278 | Alias(const char* name, int num) 279 | { 280 | next = NULL; 281 | alias = new char[strlen(name) + 1]; 282 | strcpy(alias, name); 283 | str = NULL; 284 | this->num = num; 285 | }; 286 | Alias(const char* name, const char* str) 287 | { 288 | next = NULL; 289 | alias = new char[strlen(name) + 1]; 290 | strcpy(alias, name); 291 | this->str = new char[strlen(str) + 1]; 292 | strcpy(this->str, str); 293 | }; 294 | ~Alias() 295 | { 296 | if (alias) delete[] alias; 297 | if (str) delete[] str; 298 | }; 299 | }; 300 | 301 | struct ScriptContext { 302 | ScriptContext *prev, *next; 303 | char* current_script; 304 | char* next_script; 305 | int end_status; 306 | VariableInfo current_variable, pushed_variable; 307 | ScriptContext() 308 | { 309 | prev = next = NULL; 310 | current_script = next_script = NULL; 311 | } 312 | }; 313 | 314 | int readScript(char* path); 315 | int readScriptSub(FILE* fp, char** buf, int encrypt_mode); 316 | void readConfiguration(); 317 | int labelScript(); 318 | 319 | int findLabel(const char* label); 320 | 321 | char* checkComma(char* buf); 322 | void parseStr(char** buf); 323 | void readNextOp(char** buf, int* op, int* num); 324 | int calcArithmetic(int num1, int op, int num2); 325 | int parseArray(char** buf, ArrayVariable& array); 326 | int* getArrayPtr(int no, ArrayVariable& array, int offset); 327 | 328 | /* ---------------------------------------- */ 329 | /* Variable */ 330 | struct VariableData* variable_data; 331 | struct ExtendedVariableData { 332 | int no; 333 | VariableData vd; 334 | }* extended_variable_data; 335 | int num_extended_variable_data; 336 | int max_extended_variable_data; 337 | 338 | Alias root_num_alias, *last_num_alias; 339 | Alias root_str_alias, *last_str_alias; 340 | 341 | ArrayVariable *root_array_variable, *current_array_variable; 342 | 343 | char* archive_path; 344 | char* save_dir; 345 | int script_buffer_length; 346 | char* script_buffer; 347 | unsigned char* tmp_script_buf; 348 | 349 | char* string_buffer; // update only be readToken 350 | int string_counter; 351 | char* saved_string_buffer; // updated only by saveStringBuffer 352 | char* str_string_buffer; // updated only by readStr 353 | 354 | LabelInfo* label_info; 355 | int num_of_labels; 356 | 357 | bool skip_enabled; 358 | bool kidokuskip_flag; 359 | char* kidoku_buffer; 360 | 361 | bool text_flag; // true if the current token is text 362 | int end_status; 363 | bool linepage_flag; 364 | char* clickstr_list; 365 | bool english_mode; 366 | 367 | char* current_script; 368 | char* next_script; 369 | char* wait_script; // address where '@' or '//' appears 370 | 371 | char* pushed_current_script; 372 | char* pushed_next_script; 373 | 374 | bool is_internal_script; 375 | ScriptContext root_script_context, *last_script_context; 376 | 377 | unsigned char key_table[256]; 378 | bool key_table_flag; 379 | }; 380 | 381 | #endif // __SCRIPT_HANDLER_H__ 382 | -------------------------------------------------------------------------------- /ScriptParser.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ogapee/onscripter/848a60892e4d721459e8d1051e1b8fe45164c3e9/ScriptParser.cpp -------------------------------------------------------------------------------- /ScriptParser.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ogapee/onscripter/848a60892e4d721459e8d1051e1b8fe45164c3e9/ScriptParser.h -------------------------------------------------------------------------------- /conv_shared.cpp: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * conv_shared.cpp - Shared code of sarconv and nsaconv 4 | * 5 | * Copyright (c) 2001-2018 Ogapee. All rights reserved. 6 | * 7 | * ogapee@aqua.dti2.ne.jp 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | extern "C" { 28 | #include 29 | }; 30 | #include 31 | #include "resize_image.h" 32 | 33 | int scale_ratio_upper; 34 | int scale_ratio_lower; 35 | 36 | unsigned char* rescaled_tmp2_buffer = NULL; 37 | size_t rescaled_tmp2_length = 0; 38 | unsigned char* rescaled_tmp_buffer = NULL; 39 | size_t rescaled_tmp_length = 0; 40 | 41 | static unsigned char* restored_buffer = NULL; 42 | static size_t restored_length = 0; 43 | 44 | #define INPUT_BUFFER_SIZE 4096 45 | typedef struct { 46 | struct jpeg_source_mgr pub; 47 | 48 | unsigned char* buf; 49 | size_t left; 50 | } my_source_mgr; 51 | 52 | typedef struct { 53 | struct jpeg_destination_mgr pub; 54 | 55 | unsigned char* buf; 56 | size_t left; 57 | } my_destination_mgr; 58 | 59 | void rescaleImage(unsigned char* original_buffer, int width, int height, int byte_per_pixel, 60 | bool src_pad_flag, bool dst_pad_flag, bool palette_flag) 61 | { 62 | size_t width_pad = 0; 63 | if (src_pad_flag) width_pad = (4 - width * byte_per_pixel % 4) % 4; 64 | 65 | size_t w = (int)(width * scale_ratio_upper / scale_ratio_lower); 66 | size_t h = (int)(height * scale_ratio_upper / scale_ratio_lower); 67 | if (w == 0) w = 1; 68 | if (h == 0) h = 1; 69 | size_t w_pad = 0; 70 | if (dst_pad_flag) w_pad = (4 - w * byte_per_pixel % 4) % 4; 71 | 72 | if ((w * byte_per_pixel + w_pad) * h > rescaled_tmp_length) { 73 | int len = (w * byte_per_pixel + w_pad) * h; 74 | if (rescaled_tmp_buffer) delete[] rescaled_tmp_buffer; 75 | rescaled_tmp_buffer = new unsigned char[len]; 76 | rescaled_tmp_length = len; 77 | } 78 | 79 | size_t len = (width * byte_per_pixel + width_pad) * (height + 1) + byte_per_pixel; 80 | if (len < 16) len = 16; 81 | if (len > rescaled_tmp2_length) { 82 | if (rescaled_tmp2_buffer) delete[] rescaled_tmp2_buffer; 83 | rescaled_tmp2_buffer = new unsigned char[len]; 84 | rescaled_tmp2_length = len; 85 | } 86 | 87 | resizeImage(rescaled_tmp_buffer, w, h, w * byte_per_pixel + w_pad, 88 | original_buffer, width, height, width * byte_per_pixel + width_pad, 89 | byte_per_pixel, rescaled_tmp2_buffer, width * byte_per_pixel + width_pad, palette_flag); 90 | } 91 | 92 | void init_source(j_decompress_ptr cinfo) 93 | { 94 | } 95 | 96 | boolean fill_input_buffer(j_decompress_ptr cinfo) 97 | { 98 | my_source_mgr* src = (my_source_mgr*)cinfo->src; 99 | 100 | src->pub.next_input_byte = src->buf; 101 | src->pub.bytes_in_buffer = src->left; 102 | 103 | return TRUE; 104 | } 105 | 106 | void skip_input_data(j_decompress_ptr cinfo, long num_bytes) 107 | { 108 | my_source_mgr* src = (my_source_mgr*)cinfo->src; 109 | 110 | src->pub.next_input_byte += (size_t)num_bytes; 111 | src->pub.bytes_in_buffer -= (size_t)num_bytes; 112 | } 113 | 114 | void term_source(j_decompress_ptr cinfo) 115 | { 116 | } 117 | 118 | void init_destination(j_compress_ptr cinfo) 119 | { 120 | my_destination_mgr* dest = (my_destination_mgr*)cinfo->dest; 121 | 122 | dest->pub.next_output_byte = dest->buf; 123 | dest->pub.free_in_buffer = dest->left; 124 | } 125 | 126 | boolean empty_output_buffer(j_compress_ptr cinfo) 127 | { 128 | my_destination_mgr* dest = (my_destination_mgr*)cinfo->dest; 129 | 130 | dest->pub.next_output_byte = dest->buf; 131 | dest->pub.free_in_buffer = dest->left; 132 | 133 | return TRUE; 134 | } 135 | 136 | void term_destination(j_compress_ptr cinfo) 137 | { 138 | } 139 | 140 | size_t rescaleJPEGWrite(unsigned int width, unsigned int height, int byte_per_pixel, unsigned char** rescaled_buffer, 141 | int quality, bool bmp2jpeg_flag) 142 | { 143 | jpeg_error_mgr jerr; 144 | struct jpeg_compress_struct cinfo2; 145 | JSAMPROW row_pointer[1]; 146 | 147 | cinfo2.err = jpeg_std_error(&jerr); 148 | jpeg_create_compress(&cinfo2); 149 | 150 | cinfo2.dest = (struct jpeg_destination_mgr*)(*cinfo2.mem->alloc_small)((j_common_ptr)&cinfo2, JPOOL_PERMANENT, 151 | sizeof(my_destination_mgr)); 152 | my_destination_mgr* dest = (my_destination_mgr*)cinfo2.dest; 153 | 154 | dest->buf = *rescaled_buffer; 155 | dest->left = restored_length; 156 | 157 | dest->pub.init_destination = init_destination; 158 | dest->pub.empty_output_buffer = empty_output_buffer; 159 | dest->pub.term_destination = term_destination; 160 | 161 | cinfo2.image_width = (int)(width * scale_ratio_upper / scale_ratio_lower); 162 | if (cinfo2.image_width == 0) cinfo2.image_width = 1; 163 | cinfo2.image_height = (int)(height * scale_ratio_upper / scale_ratio_lower); 164 | if (cinfo2.image_height == 0) cinfo2.image_height = 1; 165 | cinfo2.input_components = byte_per_pixel; 166 | if (cinfo2.input_components == 1) 167 | cinfo2.in_color_space = JCS_GRAYSCALE; 168 | else 169 | cinfo2.in_color_space = JCS_RGB; 170 | 171 | jpeg_set_defaults(&cinfo2); 172 | jpeg_set_quality(&cinfo2, quality, TRUE); 173 | cinfo2.optimize_coding = TRUE; 174 | // jpeg_simple_progression (&cinfo2); 175 | jpeg_start_compress(&cinfo2, TRUE); 176 | 177 | int row_stride = cinfo2.image_width * byte_per_pixel; 178 | 179 | while (cinfo2.next_scanline < cinfo2.image_height) { 180 | if (bmp2jpeg_flag) { 181 | unsigned char* src = row_pointer[0] = &rescaled_tmp_buffer[(cinfo2.image_height - 1 - cinfo2.next_scanline) * row_stride]; 182 | for (unsigned int i = 0; i < cinfo2.image_width; i++, src += 3) { 183 | unsigned char tmp = src[2]; 184 | src[2] = src[0]; 185 | src[0] = tmp; 186 | } 187 | } 188 | else { 189 | row_pointer[0] = &rescaled_tmp_buffer[cinfo2.next_scanline * row_stride]; 190 | } 191 | jpeg_write_scanlines(&cinfo2, row_pointer, 1); 192 | } 193 | 194 | jpeg_finish_compress(&cinfo2); 195 | size_t datacount = dest->left - dest->pub.free_in_buffer; 196 | 197 | jpeg_destroy_compress(&cinfo2); 198 | 199 | return datacount; 200 | } 201 | 202 | size_t rescaleJPEG(unsigned char* original_buffer, size_t length, unsigned char** rescaled_buffer, int quality) 203 | { 204 | struct jpeg_decompress_struct cinfo; 205 | jpeg_error_mgr jerr; 206 | 207 | cinfo.err = jpeg_std_error(&jerr); 208 | jpeg_create_decompress(&cinfo); 209 | 210 | cinfo.src = (struct jpeg_source_mgr*)(*cinfo.mem->alloc_small)((j_common_ptr)&cinfo, JPOOL_PERMANENT, 211 | sizeof(my_source_mgr)); 212 | my_source_mgr* src = (my_source_mgr*)cinfo.src; 213 | 214 | src->buf = original_buffer; 215 | src->left = length; 216 | 217 | src->pub.init_source = init_source; 218 | src->pub.fill_input_buffer = fill_input_buffer; 219 | src->pub.skip_input_data = skip_input_data; 220 | src->pub.resync_to_restart = jpeg_resync_to_restart; 221 | src->pub.term_source = term_source; 222 | 223 | src->pub.bytes_in_buffer = 0; 224 | src->pub.next_input_byte = NULL; 225 | 226 | jpeg_read_header(&cinfo, TRUE); 227 | jpeg_start_decompress(&cinfo); 228 | 229 | if (cinfo.output_width * cinfo.output_height * cinfo.output_components + 0x400 > restored_length) { 230 | restored_length = cinfo.output_width * cinfo.output_height * cinfo.output_components + 0x400; 231 | if (restored_buffer) delete[] restored_buffer; 232 | restored_buffer = new unsigned char[restored_length]; 233 | if (*rescaled_buffer) delete[] *rescaled_buffer; 234 | *rescaled_buffer = new unsigned char[restored_length]; 235 | } 236 | int row_stride = cinfo.output_width * cinfo.output_components; 237 | 238 | JSAMPARRAY buf = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, 1); 239 | 240 | unsigned char* buf_p = restored_buffer; 241 | while (cinfo.output_scanline < cinfo.output_height) { 242 | jpeg_read_scanlines(&cinfo, buf, 1); 243 | memcpy(buf_p, buf[0], row_stride); 244 | buf_p += cinfo.output_width * cinfo.output_components; 245 | } 246 | 247 | rescaleImage(restored_buffer, cinfo.output_width, cinfo.output_height, cinfo.output_components, false, false, false); 248 | 249 | size_t datacount = rescaleJPEGWrite(cinfo.output_width, cinfo.output_height, cinfo.output_components, rescaled_buffer, quality, false); 250 | jpeg_destroy_decompress(&cinfo); 251 | 252 | return datacount; 253 | } 254 | 255 | void rescaleBMPWrite(unsigned char* original_buffer, size_t total_size, int width, int height, unsigned char** rescaled_buffer) 256 | { 257 | int buffer_offset = original_buffer[10] + (original_buffer[11] << 8); 258 | memcpy(*rescaled_buffer, original_buffer, buffer_offset); 259 | memcpy(*rescaled_buffer + buffer_offset, rescaled_tmp_buffer, total_size - buffer_offset); 260 | 261 | *(*rescaled_buffer + 2) = total_size & 0xff; 262 | *(*rescaled_buffer + 3) = (total_size >> 8) & 0xff; 263 | *(*rescaled_buffer + 4) = (total_size >> 16) & 0xff; 264 | *(*rescaled_buffer + 5) = (total_size >> 24) & 0xff; 265 | *(*rescaled_buffer + 18) = width & 0xff; 266 | *(*rescaled_buffer + 19) = (width >> 8) & 0xff; 267 | *(*rescaled_buffer + 20) = (width >> 16) & 0xff; 268 | *(*rescaled_buffer + 21) = (width >> 24) & 0xff; 269 | *(*rescaled_buffer + 22) = height & 0xff; 270 | *(*rescaled_buffer + 23) = (height >> 8) & 0xff; 271 | *(*rescaled_buffer + 24) = (height >> 16) & 0xff; 272 | *(*rescaled_buffer + 25) = (height >> 24) & 0xff; 273 | *(*rescaled_buffer + 34) = 0; 274 | *(*rescaled_buffer + 35) = 0; 275 | *(*rescaled_buffer + 36) = 0; 276 | *(*rescaled_buffer + 37) = 0; 277 | 278 | #if 0 279 | FILE *fp = fopen( "test.bmp", "wb" ); 280 | fwrite( *rescaled_buffer, 1, width2 * height2 * byte_per_pixel + 54 + color_num*4, fp ); 281 | fclose(fp); 282 | getchar(); 283 | #endif 284 | } 285 | 286 | size_t rescaleBMP(unsigned char* original_buffer, unsigned char** rescaled_buffer, 287 | bool output_jpeg_flag, int quality) 288 | { 289 | if (original_buffer[14] != 40) { 290 | if (original_buffer[14] == 12) 291 | fprintf(stderr, " OS/2 format is not supported.\n"); 292 | else 293 | fprintf(stderr, " this bitmap can't be handled.\n"); 294 | exit(-1); 295 | } 296 | 297 | int buffer_offset = original_buffer[10] + (original_buffer[11] << 8); 298 | int width = original_buffer[18] + (original_buffer[19] << 8); 299 | int height = original_buffer[22] + (original_buffer[23] << 8); 300 | 301 | int bit_per_pixel = original_buffer[28]; 302 | if (bit_per_pixel == 1 || bit_per_pixel == 4) { 303 | fprintf(stderr, " bit_per_pixel %d is not supported.\n", bit_per_pixel); 304 | exit(-1); 305 | } 306 | int byte_per_pixel = bit_per_pixel / 8; 307 | int color_num = original_buffer[46] + ((int)original_buffer[47] << 8) + (original_buffer[48] << 16) + (original_buffer[49] << 24); 308 | if (bit_per_pixel == 8 && color_num == 0) color_num = 256; 309 | 310 | bool palette_flag = false; 311 | if (bit_per_pixel == 8) palette_flag = true; 312 | if (palette_flag) output_jpeg_flag = false; 313 | 314 | size_t width2 = (int)(width * scale_ratio_upper / scale_ratio_lower); 315 | if (width2 == 0) width2 = 1; 316 | size_t width2_pad = (4 - width2 * byte_per_pixel % 4) % 4; 317 | 318 | size_t height2 = (int)(height * scale_ratio_upper / scale_ratio_lower); 319 | if (height2 == 0) height2 = 1; 320 | 321 | size_t total_size = (width2 * byte_per_pixel + width2_pad) * height2 + buffer_offset; 322 | if (total_size + 0x400 > restored_length) { 323 | restored_length = total_size + 0x400; 324 | if (restored_buffer) delete[] restored_buffer; 325 | restored_buffer = new unsigned char[restored_length]; 326 | if (*rescaled_buffer) delete[] *rescaled_buffer; 327 | *rescaled_buffer = new unsigned char[restored_length]; 328 | } 329 | 330 | if (output_jpeg_flag) { 331 | rescaleImage(original_buffer + buffer_offset, width, height, byte_per_pixel, true, false, palette_flag); 332 | total_size = rescaleJPEGWrite(width, height, byte_per_pixel, rescaled_buffer, quality, true); 333 | } 334 | else { 335 | rescaleImage(original_buffer + buffer_offset, width, height, byte_per_pixel, true, true, palette_flag); 336 | rescaleBMPWrite(original_buffer, total_size, width2, height2, rescaled_buffer); 337 | } 338 | 339 | return total_size; 340 | } 341 | -------------------------------------------------------------------------------- /nsaconv.cpp: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * nsaconv.cpp - Images in NSA archive are re-scaled to 320x240 size 4 | * 5 | * Copyright (c) 2001-2014 Ogapee. All rights reserved. 6 | * 7 | * ogapee@aqua.dti2.ne.jp 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include "NsaReader.h" 30 | 31 | extern int scale_ratio_upper; 32 | extern int scale_ratio_lower; 33 | 34 | extern size_t rescaleJPEG(unsigned char* original_buffer, size_t length, unsigned char** rescaled_buffer, 35 | int quality); 36 | extern size_t rescaleBMP(unsigned char* original_buffer, unsigned char** rescaled_buffer, 37 | bool output_jpeg_flag, int quality); 38 | 39 | #ifdef main 40 | #undef main 41 | #endif 42 | 43 | void help() 44 | { 45 | fprintf(stderr, "Usage: nsaconv [-e] [-j] [-ns2] [-ns3] [-q quality] src_width dst_width src_archive_file dst_archive_file\n"); 46 | fprintf(stderr, " quality ... 0 to 100\n"); 47 | fprintf(stderr, " src_width ... 640 or 800\n"); 48 | fprintf(stderr, " dst_width ... 176, 220, 320, 360, 384, 640, etc.\n"); 49 | exit(-1); 50 | } 51 | 52 | int main(int argc, char** argv) 53 | { 54 | NsaReader cSR; 55 | unsigned int nsa_offset = 0; 56 | unsigned long length, offset = 0, buffer_length = 0; 57 | unsigned char *buffer = NULL, *rescaled_buffer = NULL; 58 | unsigned int i, count; 59 | int archive_type = BaseReader::ARCHIVE_TYPE_NSA; 60 | bool enhanced_flag = false; 61 | bool bmp2jpeg_flag = false; 62 | int quality = 75; 63 | FILE* fp; 64 | 65 | argc--; // skip command name 66 | argv++; 67 | while (argc > 4) { 68 | if (!strcmp(argv[0], "-e")) 69 | enhanced_flag = true; 70 | else if (!strcmp(argv[0], "-j")) 71 | bmp2jpeg_flag = true; 72 | else if (!strcmp(argv[0], "-ns2")) 73 | nsa_offset = 1; 74 | else if (!strcmp(argv[0], "-ns3")) 75 | nsa_offset = 2; 76 | else if (!strcmp(argv[0], "-q")) { 77 | argc--; 78 | argv++; 79 | quality = atoi(argv[0]); 80 | } 81 | argc--; 82 | argv++; 83 | } 84 | if (argc != 4) help(); 85 | if (bmp2jpeg_flag) enhanced_flag = false; 86 | 87 | scale_ratio_lower = atoi(argv[0]); // src width 88 | if (scale_ratio_lower != 640 && scale_ratio_lower != 800) help(); 89 | 90 | scale_ratio_upper = atoi(argv[1]); // dst width 91 | 92 | if ((fp = fopen(argv[3], "wb")) == NULL) { 93 | fprintf(stderr, "can't open file %s for writing.\n", argv[3]); 94 | exit(-1); 95 | } 96 | cSR.openForConvert(argv[2], archive_type, nsa_offset); 97 | count = cSR.getNumFiles(); 98 | 99 | SarReader::FileInfo sFI; 100 | 101 | for (i = 0; i < count; i++) { 102 | sFI = cSR.getFileByIndex(i); 103 | printf("%d/%d\n", i, count); 104 | if (i == 0) offset = sFI.offset; 105 | length = cSR.getFileLength(sFI.name); 106 | if (length > buffer_length) { 107 | if (buffer) delete[] buffer; 108 | buffer = new unsigned char[length]; 109 | buffer_length = length; 110 | } 111 | 112 | sFI.offset = offset; 113 | if ((strlen(sFI.name) > 3 && !strcmp(sFI.name + strlen(sFI.name) - 3, "JPG")) || 114 | (strlen(sFI.name) > 4 && !strcmp(sFI.name + strlen(sFI.name) - 4, "JPEG"))) { 115 | if (cSR.getFile(sFI.name, buffer) != length) { 116 | fprintf(stderr, "file %s can't be retrieved %ld\n", sFI.name, length); 117 | continue; 118 | } 119 | sFI.length = rescaleJPEG(buffer, length, &rescaled_buffer, quality); 120 | cSR.putFile(fp, i, sFI.offset, sFI.length, sFI.length, sFI.compression_type, true, rescaled_buffer); 121 | } 122 | else if (strlen(sFI.name) > 3 && !strcmp(sFI.name + strlen(sFI.name) - 3, "BMP")) { 123 | if (cSR.getFile(sFI.name, buffer) != length) { 124 | fprintf(stderr, "file %s can't be retrieved %ld\n", sFI.name, length); 125 | continue; 126 | } 127 | sFI.length = rescaleBMP(buffer, &rescaled_buffer, bmp2jpeg_flag, quality); 128 | cSR.putFile(fp, i, sFI.offset, sFI.length, sFI.length, enhanced_flag ? BaseReader::NBZ_COMPRESSION : sFI.compression_type, true, rescaled_buffer); 129 | } 130 | else if (enhanced_flag && strlen(sFI.name) > 3 && !strcmp(sFI.name + strlen(sFI.name) - 3, "WAV")) { 131 | if (cSR.getFile(sFI.name, buffer) != length) { 132 | fprintf(stderr, "file %s can't be retrieved %ld\n", sFI.name, length); 133 | continue; 134 | } 135 | sFI.length = cSR.putFile(fp, i, sFI.offset, sFI.length, length, BaseReader::NBZ_COMPRESSION, true, buffer); 136 | } 137 | else { 138 | cSR.putFile(fp, i, sFI.offset, sFI.length, sFI.original_length, sFI.compression_type, false, buffer); 139 | } 140 | 141 | offset += sFI.length; 142 | } 143 | cSR.writeHeader(fp, archive_type, nsa_offset); 144 | 145 | fclose(fp); 146 | 147 | if (rescaled_buffer) delete[] rescaled_buffer; 148 | if (buffer) delete[] buffer; 149 | 150 | return 0; 151 | } 152 | -------------------------------------------------------------------------------- /nsadec.cpp: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * nsadec.cpp - NSA archive decoder 4 | * 5 | * Copyright (c) 2001-2015 Ogapee. All rights reserved. 6 | * 7 | * ogapee@aqua.dti2.ne.jp 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include "NsaReader.h" 31 | 32 | extern int errno; 33 | 34 | int main(int argc, char** argv) 35 | { 36 | NsaReader cNR; 37 | unsigned int nsa_offset = 0; 38 | unsigned long length; 39 | unsigned char* buffer; 40 | char file_name[256], dir_name[256]; 41 | unsigned int i, j, count; 42 | int archive_type = BaseReader::ARCHIVE_TYPE_NSA; 43 | FILE* fp; 44 | struct stat file_stat; 45 | 46 | if (argc >= 2) { 47 | while (argc > 2) { 48 | if (!strcmp(argv[1], "-ns2")) 49 | archive_type = BaseReader::ARCHIVE_TYPE_NS2; 50 | else if (!strcmp(argv[1], "-offset")) { 51 | nsa_offset = atoi(argv[2]); 52 | argc--; 53 | argv++; 54 | } 55 | argc--; 56 | argv++; 57 | } 58 | } 59 | if (argc != 2) { 60 | fprintf(stderr, "Usage: nsadec [-offset ##] [-ns2] arc_file\n"); 61 | exit(-1); 62 | } 63 | cNR.openForConvert(argv[1], archive_type, nsa_offset); 64 | count = cNR.getNumFiles(); 65 | 66 | SarReader::FileInfo sFI; 67 | 68 | for (i = 0; i < count; i++) { 69 | sFI = cNR.getFileByIndex(i); 70 | length = cNR.getFileLength(sFI.name); 71 | buffer = new unsigned char[length]; 72 | unsigned int len; 73 | if ((len = cNR.getFile(sFI.name, buffer)) != length) { 74 | // fprintf( stderr, "file %s can't be retrieved\n", sFI.name ); 75 | fprintf(stderr, "file %s is not fully retrieved %d %lu\n", sFI.name, len, length); 76 | length = sFI.length; 77 | // continue; 78 | } 79 | 80 | strcpy(file_name, sFI.name); 81 | for (j = 0; j < strlen(file_name); j++) { 82 | if (file_name[j] == '\\') { 83 | file_name[j] = '/'; 84 | strncpy(dir_name, file_name, j); 85 | dir_name[j] = '\0'; 86 | 87 | /* If the directory does'nt exist, create it */ 88 | if (stat(dir_name, &file_stat) == -1 && errno == ENOENT) 89 | mkdir(dir_name, 00755); 90 | } 91 | } 92 | 93 | if ((fp = fopen(file_name, "wb"))) { 94 | fwrite(buffer, 1, length, fp); 95 | fclose(fp); 96 | } 97 | else { 98 | printf("opening %s ... falied\n", file_name); 99 | } 100 | 101 | delete[] buffer; 102 | } 103 | 104 | exit(0); 105 | } 106 | -------------------------------------------------------------------------------- /nscriptdecode.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | int ch; 5 | while ((ch = getchar()) != EOF) putchar(ch ^ 0x84); 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /resize_image.cpp: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * resize_image.cpp - resize image using smoothing and resampling 4 | * 5 | * Copyright (c) 2001-2012 Ogapee. All rights reserved. 6 | * 7 | * ogapee@aqua.dti2.ne.jp 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #include 25 | #include 26 | 27 | static unsigned long* pixel_accum = NULL; 28 | static unsigned long* pixel_accum_num = NULL; 29 | static int pixel_accum_size = 0; 30 | static unsigned long tmp_acc[4]; 31 | static unsigned long tmp_acc_num[4]; 32 | 33 | static void calcWeightedSumColumnInit(unsigned char** src, 34 | int interpolation_height, 35 | int image_width, int image_height, int image_pixel_width, int byte_per_pixel) 36 | { 37 | int y_end = -interpolation_height / 2 + interpolation_height; 38 | 39 | memset(pixel_accum, 0, image_width * byte_per_pixel * sizeof(unsigned long)); 40 | memset(pixel_accum_num, 0, image_width * byte_per_pixel * sizeof(unsigned long)); 41 | for (int s = 0; s < byte_per_pixel; s++) { 42 | for (int i = 0; i < y_end - 1; i++) { 43 | if (i >= image_height) break; 44 | unsigned long* pa = pixel_accum + image_width * s; 45 | unsigned long* pan = pixel_accum_num + image_width * s; 46 | unsigned char* p = *src + image_pixel_width * i + s; 47 | for (int j = image_width; j != 0; j--, p += byte_per_pixel) { 48 | *pa++ += *p; 49 | (*pan++)++; 50 | } 51 | } 52 | } 53 | } 54 | 55 | static void calcWeightedSumColumn(unsigned char** src, int y, 56 | int interpolation_height, 57 | int image_width, int image_height, int image_pixel_width, int byte_per_pixel) 58 | { 59 | int y_start = y - interpolation_height / 2; 60 | int y_end = y - interpolation_height / 2 + interpolation_height; 61 | 62 | for (int s = 0; s < byte_per_pixel; s++) { 63 | if ((y_start - 1) >= 0 && (y_start - 1) < image_height) { 64 | unsigned long* pa = pixel_accum + image_width * s; 65 | unsigned long* pan = pixel_accum_num + image_width * s; 66 | unsigned char* p = *src + image_pixel_width * (y_start - 1) + s; 67 | for (int j = image_width; j != 0; j--, p += byte_per_pixel) { 68 | *pa++ -= *p; 69 | (*pan++)--; 70 | } 71 | } 72 | 73 | if ((y_end - 1) >= 0 && (y_end - 1) < image_height) { 74 | unsigned long* pa = pixel_accum + image_width * s; 75 | unsigned long* pan = pixel_accum_num + image_width * s; 76 | unsigned char* p = *src + image_pixel_width * (y_end - 1) + s; 77 | for (int j = image_width; j != 0; j--, p += byte_per_pixel) { 78 | *pa++ += *p; 79 | (*pan++)++; 80 | } 81 | } 82 | } 83 | } 84 | 85 | static void calcWeightedSum(unsigned char** dst, unsigned char** src, int x, 86 | int interpolation_width, 87 | int image_width, int byte_per_pixel) 88 | { 89 | int x_start = x - interpolation_width / 2; 90 | int x_end = x - interpolation_width / 2 + interpolation_width; 91 | 92 | for (int s = 0; s < byte_per_pixel; s++) { 93 | if ((x_start - 1) >= 0 && (x_start - 1) < image_width) { 94 | tmp_acc[s] -= pixel_accum[image_width * s + x_start - 1]; 95 | tmp_acc_num[s] -= pixel_accum_num[image_width * s + x_start - 1]; 96 | } 97 | if ((x_end - 1) >= 0 && (x_end - 1) < image_width) { 98 | tmp_acc[s] += pixel_accum[image_width * s + x_end - 1]; 99 | tmp_acc_num[s] += pixel_accum_num[image_width * s + x_end - 1]; 100 | } 101 | *(*dst)++ = (unsigned char)(tmp_acc[s] / tmp_acc_num[s]); 102 | } 103 | } 104 | 105 | void resizeImage(unsigned char* dst_buffer, int dst_width, int dst_height, int dst_total_width, 106 | unsigned char* src_buffer, int src_width, int src_height, int src_total_width, 107 | int byte_per_pixel, unsigned char* tmp_buffer, int tmp_total_width, bool palette_flag) 108 | { 109 | if (dst_width == 0 || dst_height == 0) return; 110 | 111 | unsigned char* tmp_buf = tmp_buffer; 112 | unsigned char* src_buf = src_buffer; 113 | 114 | int i, j, s; 115 | int tmp_offset = tmp_total_width - src_width * byte_per_pixel; 116 | 117 | unsigned int mx, my; 118 | 119 | if (src_width > 1) 120 | mx = 1; 121 | else 122 | mx = 0; 123 | if (src_height > 1) 124 | my = 1; 125 | else 126 | my = 0; 127 | 128 | int interpolation_width = src_width / dst_width; 129 | if (interpolation_width == 0) interpolation_width = 1; 130 | int interpolation_height = src_height / dst_height; 131 | if (interpolation_height == 0) interpolation_height = 1; 132 | 133 | if (pixel_accum_size < src_width * byte_per_pixel) { 134 | pixel_accum_size = src_width * byte_per_pixel; 135 | if (pixel_accum) delete[] pixel_accum; 136 | pixel_accum = new unsigned long[pixel_accum_size]; 137 | if (pixel_accum_num) delete[] pixel_accum_num; 138 | pixel_accum_num = new unsigned long[pixel_accum_size]; 139 | } 140 | /* smoothing */ 141 | if (byte_per_pixel >= 3) { 142 | calcWeightedSumColumnInit(&src_buf, interpolation_height, 143 | src_width, src_height, src_total_width, byte_per_pixel); 144 | for (i = 0; i < src_height; i++) { 145 | calcWeightedSumColumn(&src_buf, i, interpolation_height, 146 | src_width, src_height, src_total_width, byte_per_pixel); 147 | for (s = 0; s < byte_per_pixel; s++) { 148 | tmp_acc[s] = 0; 149 | tmp_acc_num[s] = 0; 150 | for (j = 0; j < -interpolation_width / 2 + interpolation_width - 1; j++) { 151 | if (j >= src_width) break; 152 | tmp_acc[s] += pixel_accum[src_width * s + j]; 153 | tmp_acc_num[s] += pixel_accum_num[src_width * s + j]; 154 | } 155 | } 156 | 157 | for (j = 0; j < src_width; j++) 158 | calcWeightedSum(&tmp_buf, &src_buf, j, 159 | interpolation_width, 160 | src_width, byte_per_pixel); 161 | tmp_buf += tmp_offset; 162 | } 163 | } 164 | else { 165 | tmp_buffer = src_buffer; 166 | } 167 | 168 | /* resampling */ 169 | unsigned char* dst_buf = dst_buffer; 170 | int dh1 = dst_height - 1; 171 | if (dh1 == 0) dh1 = 1; 172 | int dw1 = dst_width - 1; 173 | if (dw1 == 0) dw1 = 1; 174 | for (i = 0; i < dst_height; i++) { 175 | int y = (i << 3) * (src_height - 1) / dh1; 176 | int dy = y & 0x7; 177 | y >>= 3; 178 | for (j = 0; j < dst_width; j++) { 179 | int x = (j << 3) * (src_width - 1) / dw1; 180 | int dx = x & 0x7; 181 | x >>= 3; 182 | 183 | int k = tmp_total_width * y + x * byte_per_pixel; 184 | 185 | if (palette_flag) { // assuming byte_per_pixel=1 186 | *dst_buf++ = tmp_buffer[k]; 187 | } 188 | else { 189 | for (s = 0; s < byte_per_pixel; s++, k++) { 190 | unsigned int p; 191 | p = (8 - dx) * (8 - dy) * tmp_buffer[k]; 192 | p += dx * (8 - dy) * tmp_buffer[k + mx * byte_per_pixel]; 193 | p += (8 - dx) * dy * tmp_buffer[k + my * tmp_total_width]; 194 | p += dx * dy * tmp_buffer[k + mx * byte_per_pixel + my * tmp_total_width]; 195 | *dst_buf++ = (unsigned char)(p >> 6); 196 | } 197 | } 198 | } 199 | for (j = 0; j < dst_total_width - dst_width * byte_per_pixel; j++) 200 | *dst_buf++ = 0; 201 | } 202 | 203 | /* pixels at the corners are preserved */ 204 | for (i = 0; i < byte_per_pixel; i++) { 205 | dst_buffer[i] = src_buffer[i]; 206 | dst_buffer[(dst_width - 1) * byte_per_pixel + i] = src_buffer[(src_width - 1) * byte_per_pixel + i]; 207 | dst_buffer[(dst_height - 1) * dst_total_width + i] = src_buffer[(src_height - 1) * src_total_width + i]; 208 | dst_buffer[(dst_height - 1) * dst_total_width + (dst_width - 1) * byte_per_pixel + i] = 209 | src_buffer[(src_height - 1) * src_total_width + (src_width - 1) * byte_per_pixel + i]; 210 | } 211 | } 212 | -------------------------------------------------------------------------------- /resize_image.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * resize_image.h - resize image using smoothing and resampling 4 | * 5 | * Copyright (c) 2001-2004 Ogapee. All rights reserved. 6 | * 7 | * ogapee@aqua.dti2.ne.jp 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | void resizeImage(unsigned char* dst_buffer, int dst_width, int dst_height, int dst_total_width, 25 | unsigned char* src_buffer, int src_width, int src_height, int src_total_width, 26 | int byte_per_pixel, unsigned char* tmp_buffer, int tmp_total_width, bool palette_flag); 27 | -------------------------------------------------------------------------------- /sarconv.cpp: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * sarconv.cpp - Images in SAR archive are re-scaled to 320x240 size 4 | * 5 | * Copyright (c) 2001-2006 Ogapee. All rights reserved. 6 | * 7 | * ogapee@aqua.dti2.ne.jp 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include "SarReader.h" 30 | 31 | extern int scale_ratio_upper; 32 | extern int scale_ratio_lower; 33 | 34 | extern size_t rescaleJPEG(unsigned char* original_buffer, size_t length, unsigned char** rescaled_buffer, 35 | int quality); 36 | extern size_t rescaleBMP(unsigned char* original_buffer, unsigned char** rescaled_buffer, 37 | bool output_jpeg_flag, int quality); 38 | 39 | #ifdef main 40 | #undef main 41 | #endif 42 | 43 | void help() 44 | { 45 | fprintf(stderr, "Usage: sarconv [-j] [-q quality] src_width dst_width src_archive_file dst_archive_file\n"); 46 | fprintf(stderr, " quality ... 0 to 100\n"); 47 | fprintf(stderr, " src_width ... 640 or 800\n"); 48 | fprintf(stderr, " dst_width ... 176, 220, 320, 360, 384, 640, etc.\n"); 49 | exit(-1); 50 | } 51 | 52 | int main(int argc, char** argv) 53 | { 54 | SarReader cSR; 55 | unsigned long length, offset = 0, buffer_length = 0; 56 | unsigned char *buffer = NULL, *rescaled_buffer = NULL; 57 | unsigned int i, count; 58 | bool bmp2jpeg_flag = false; 59 | int quality = 75; 60 | FILE* fp; 61 | 62 | argc--; // skip command name 63 | argv++; 64 | while (argc > 4) { 65 | if (!strcmp(argv[0], "-j")) 66 | bmp2jpeg_flag = true; 67 | else if (!strcmp(argv[0], "-q")) { 68 | argc--; 69 | argv++; 70 | quality = atoi(argv[0]); 71 | } 72 | argc--; 73 | argv++; 74 | } 75 | if (argc != 4) help(); 76 | 77 | scale_ratio_lower = atoi(argv[0]); // src width 78 | if (scale_ratio_lower != 640 && scale_ratio_lower != 800) help(); 79 | 80 | scale_ratio_upper = atoi(argv[1]); // dst width 81 | 82 | if ((fp = fopen(argv[3], "wb")) == NULL) { 83 | fprintf(stderr, "can't open file %s for writing.\n", argv[3]); 84 | exit(-1); 85 | } 86 | if (cSR.open(argv[2]) != 0) { 87 | fprintf(stderr, "can't open file %s\n", argv[2]); 88 | exit(-1); 89 | } 90 | count = cSR.getNumFiles(); 91 | 92 | SarReader::FileInfo sFI; 93 | 94 | for (i = 0; i < count; i++) { 95 | printf("%d/%d\n", i, count); 96 | sFI = cSR.getFileByIndex(i); 97 | if (i == 0) offset = sFI.offset; 98 | length = cSR.getFileLength(sFI.name); 99 | if (length > buffer_length) { 100 | if (buffer) delete[] buffer; 101 | buffer = new unsigned char[length]; 102 | buffer_length = length; 103 | } 104 | 105 | sFI.offset = offset; 106 | if ((strlen(sFI.name) > 3 && !strcmp(sFI.name + strlen(sFI.name) - 3, "JPG")) || 107 | (strlen(sFI.name) > 4 && !strcmp(sFI.name + strlen(sFI.name) - 4, "JPEG"))) { 108 | if (cSR.getFile(sFI.name, buffer) != length) { 109 | fprintf(stderr, "file %s can't be retrieved %ld\n", sFI.name, length); 110 | continue; 111 | } 112 | sFI.length = rescaleJPEG(buffer, length, &rescaled_buffer, quality); 113 | cSR.putFile(fp, i, sFI.offset, sFI.length, sFI.length, true, rescaled_buffer); 114 | } 115 | else if (strlen(sFI.name) > 3 && !strcmp(sFI.name + strlen(sFI.name) - 3, "BMP")) { 116 | if (cSR.getFile(sFI.name, buffer) != length) { 117 | fprintf(stderr, "file %s can't be retrieved %ld\n", sFI.name, length); 118 | continue; 119 | } 120 | sFI.length = rescaleBMP(buffer, &rescaled_buffer, bmp2jpeg_flag, quality); 121 | cSR.putFile(fp, i, sFI.offset, sFI.length, sFI.length, true, rescaled_buffer); 122 | } 123 | else { 124 | cSR.putFile(fp, i, sFI.offset, sFI.length, sFI.original_length, false, buffer); 125 | } 126 | 127 | offset += sFI.length; 128 | } 129 | cSR.writeHeader(fp); 130 | 131 | fclose(fp); 132 | 133 | if (rescaled_buffer) delete[] rescaled_buffer; 134 | if (buffer) delete[] buffer; 135 | 136 | return 0; 137 | } 138 | -------------------------------------------------------------------------------- /sardec.cpp: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * sardec.cpp - SAR archive decoder 4 | * 5 | * Copyright (c) 2001-2004 Ogapee. All rights reserved. 6 | * 7 | * ogapee@aqua.dti2.ne.jp 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include "SarReader.h" 31 | 32 | extern int errno; 33 | 34 | int main(int argc, char** argv) 35 | { 36 | SarReader cSR; 37 | unsigned long length, buffer_length = 0; 38 | unsigned char* buffer = NULL; 39 | char file_name[256], dir_name[256]; 40 | unsigned int i, j, count; 41 | FILE* fp; 42 | struct stat file_stat; 43 | 44 | if (argc != 2) { 45 | fprintf(stderr, "Usage: sardec arc_file\n"); 46 | exit(-1); 47 | } 48 | if (cSR.open(argv[1]) != 0) { 49 | fprintf(stderr, "can't open file %s\n", argv[1]); 50 | exit(-1); 51 | } 52 | count = cSR.getNumFiles(); 53 | 54 | SarReader::FileInfo sFI; 55 | 56 | for (i = 0; i < count; i++) { 57 | sFI = cSR.getFileByIndex(i); 58 | 59 | length = cSR.getFileLength(sFI.name); 60 | 61 | if (length > buffer_length) { 62 | if (buffer) delete[] buffer; 63 | buffer = new unsigned char[length]; 64 | buffer_length = length; 65 | } 66 | if (cSR.getFile(sFI.name, buffer) != length) { 67 | fprintf(stderr, "file %s can't be retrieved\n", sFI.name); 68 | continue; 69 | } 70 | 71 | strcpy(file_name, sFI.name); 72 | for (j = 0; j < strlen(file_name); j++) { 73 | if (file_name[j] == '\\') { 74 | file_name[j] = '/'; 75 | strncpy(dir_name, file_name, j); 76 | dir_name[j] = '\0'; 77 | 78 | /* If the directory does'nt exist, create it */ 79 | if (stat(dir_name, &file_stat) == -1 && errno == ENOENT) 80 | mkdir(dir_name, 00755); 81 | } 82 | } 83 | 84 | printf("opening %s\n", file_name); 85 | if ((fp = fopen(file_name, "wb"))) { 86 | fwrite(buffer, 1, length, fp); 87 | fclose(fp); 88 | } 89 | else { 90 | printf(" ... falied\n"); 91 | } 92 | } 93 | 94 | if (buffer) delete[] buffer; 95 | 96 | exit(0); 97 | } 98 | -------------------------------------------------------------------------------- /simple_aviplay.cpp: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * 3 | * simple_aviplay.cpp - sample program for AVIWrapper class 4 | * 5 | * Copyright (c) 2001-2004 Ogapee. All rights reserved. 6 | * 7 | * ogapee@aqua.dti2.ne.jp 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include "AVIWrapper.h" 31 | 32 | #define DEFAULT_AUDIOBUF 4096 33 | #define ONS_MIX_CHANNELS 50 34 | 35 | int main(int argc, char** argv) 36 | { 37 | if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_AUDIO) < 0) { 38 | fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); 39 | exit(-1); 40 | } 41 | 42 | AVIWrapper avi; 43 | if (avi.init(argv[1], true)) exit(-1); 44 | SDL_Surface* screen_surface = SDL_SetVideoMode(avi.getWidth(), avi.getHeight(), 32, SDL_SWSURFACE); 45 | if (avi.initAV(screen_surface, true)) exit(-1); 46 | avi.play(true); 47 | 48 | exit(0); 49 | } 50 | -------------------------------------------------------------------------------- /version.h: -------------------------------------------------------------------------------- 1 | #define ONS_VERSION "20230825" 2 | #define NSC_VERSION 296 3 | --------------------------------------------------------------------------------