Compare commits

..
92 Commits
Author SHA1 Message Date
kichikuou 2c9079c875 Version 2.17.1 2026-01-10 16:13:16 +09:00
kichikuou 54b8d6c993 android/README.md: Add Obtainium installation instructions 2026-01-10 14:57:43 +09:00
kichikuou f2fe6b9724 SACT: Ctrl key cancels SACT.Wait and SACT.TimerWait
This fixes an issue where the roulette in Rance 5D could not be fast
forwarded using the Ctrl key.
2026-01-09 16:16:13 +09:00
kichikuou 38dc9a7b0b Refactor sacttimer.c 2026-01-09 13:14:48 +09:00
kichikuou d2ac3889b5 QE/LE: Handle for paths with subdirectories correctly
This resolves issues where saving to and loading from paths with
subdirectories (e.g., "Save\file.asd") would fail.

The original problems were:
 1. Writing failure: A path mismatch between directory creation in
    commandQE and file writing in fc_open.
 2. Loading failure: fc_search could not handle paths containing
    directory separators, preventing saved files in subdirectories from
    being found.

This commit addresses these issues with the following changes:
 - fc_open now automatically creates parent directories when writing a
   file.
 - fc_search is updated to support two modes:
     - It performs a case-insensitive search for simple filenames
       (preserving original behavior).
     - It performs a case-sensitive existence check for full paths.

Fixes #74.
2026-01-09 08:31:40 +09:00
kichikuou 0342141358 Add is_available function to CD-ROM devices
Now `SI 2` command returns zero if no audio track is available.
2025-11-28 10:45:24 +09:00
kichikuou 8806bc9545 Version 2.17.0 2025-11-09 22:27:45 +09:00
kichikuou 5e62405f17 Move patch/ to misc/patch/ 2025-11-09 22:26:15 +09:00
kichikuou 714c7d44b5 Android: Update SDL to 2.32.10 2025-11-09 22:08:54 +09:00
kichikuou 0f6d4e2343 Add Streamer Mode with -censor option
This introduces "Streamer Mode" to mosaic specified NSFW images, making
the game suitable for streaming or public viewing. This feature is
enabled via the '-censor <file>' command-line option, which takes a file
containing a list of image numbers to be filtered.
2025-11-09 11:47:13 +09:00
kichikuou f1536a801a QE/LE: Handle backslashes in filenames
Rance 5D uses filename `Save\\Rance5dSystem.asd`. This caused issues:

- On Windows, saving would fail if the `Save` directory did not exist.
- On other platforms, files were created with literal backslashes in
  their names.

This change addresses these problems by:

- In commandQE, normalizing backslashes to forward slashes in the path
  and ensuring that the target directory exists by calling mkdir_p().
- In commandLE, first attempting to load files with normalized forward
  slashes. If that fails, it retries with the original path (containing
  backslashes) for compatibility with older saves.
2025-11-06 11:05:23 +09:00
kichikuou ab372b7873 Unify old and new command implementations
Consolidate logic for parsing string arguments by introducing a
parameter to handle different terminators.
2025-11-06 09:39:51 +09:00
kichikuou 2c02f40dc4 Move uppercase commands from cmd2F.c to cmd<first_letter>.c 2025-11-06 09:39:46 +09:00
kichikuou a395366cf8 Version 2.16.1 2025-08-28 13:00:30 +09:00
kichikuou e416fc20d3 CI: Disable portmidi on mingw32
mingw-w64-i686-portmidi is no longer provided.
2025-08-28 12:47:02 +09:00
kichikuou 7d03fc6757 sactlog: Hold log text in UTF-8 2025-08-28 12:24:49 +09:00
kichikuou e3b8c90611 sactlog: Draw text using gfx_drawString()
This fixes #71. It was a regression by commit ec071d4.
2025-08-28 11:41:51 +09:00
kichikuou 361ca89016 Windows: #undef min / max in portab.h 2025-06-20 08:11:35 +09:00
kichikuou 5bd4622031 Version 2.16.0 2025-06-13 17:20:47 +09:00
kichikuou c7c0f69ec4 Split sdl_core.h to event.h and editor.h
And rename sdl_event.c to event.c, sdl_input.c to editor.c.
2025-06-11 10:12:25 +09:00
kichikuou f38a3eda5c Merge sdl_cursor.c to cursor.c 2025-06-11 10:12:22 +09:00
kichikuou dc17b78365 Move miscellaneous low-level functions to system.[ch] 2025-06-11 09:23:44 +09:00
kichikuou b9f68eedd3 Move joystick initialization code to sdl_event.c 2025-06-11 09:23:44 +09:00
kichikuou adf362ea57 Rename sdl_effect_* to effect_* 2025-06-11 09:23:44 +09:00
kichikuou b5bf439b8e Remove graphics.h 2025-06-11 09:23:42 +09:00
kichikuou 9a01d28075 Move gfx_* functions from sdl_core.h to gfx.h 2025-06-11 09:22:36 +09:00
kichikuou 945dbd7722 Rename graphics functions from sdl_* to gfx_*
And rename sdl_{video,draw,image}.c to gfx_{video,draw,image}.c.
2025-06-10 15:00:27 +09:00
kichikuou 1c54487041 cmake: Use new policies up to CMake 4.0 2025-06-10 13:58:40 +09:00
kichikuou 92389289da Android: Add "clear save files" launcher menu command 2025-06-10 13:17:27 +09:00
kichikuou 4de03cc77f Move font license files to license/ 2025-05-30 20:54:28 +09:00
kichikuou 5a81ac6fc8 Windows: Add cancel button to text/number input dialog 2025-05-30 16:06:29 +09:00
kichikuou d7bac22059 Windows: Implement number input dialog (NI command)
Fixes #68.
2025-05-30 16:06:26 +09:00
kichikuou 8d4424061d Switch JPEG decoder to NanoJPEG and disable fancy upsampling
Graymerca uses JPEG images for map tiles, which suffers from color
bleeding due to chroma upsampling in the JPEG decoder.

Since stb_image cannot disable the bilinear upsampling filter, this
switches the JPEG decoder to NanoJPEG.

Fixes #67.
2025-05-29 08:39:59 +09:00
kichikuou 6c692e44e5 Version 2.15.1 2025-05-14 15:06:20 +09:00
kichikuou ec071d4e8a dt_drawtext_col: Fix blend mode
This fixes #66. It was a regression by commit 6b646b3.
2025-05-14 12:46:30 +09:00
kichikuou 904e10daa7 Version 2.15.0 2025-04-21 11:20:31 +09:00
kichikuou 65b6da3f2a emscripten: Export HEAPU8 and HEAP16
Used in Kichikou on Web shell.
2025-04-21 10:12:43 +09:00
kichikuou 3f495b72c1 Fix message waiting in Rance 2 intro
By recreating a bug of the ZW command in system35.exe.
2025-04-21 09:43:01 +09:00
kichikuou 90670477c6 Fix uncancellable message wait mode (ZW 256-511) 2025-04-21 09:42:58 +09:00
kichikuou 566ebb503f Fix PS and PP commands
This was a regression introduced by commit c1018d9.

Fixes #65.
2025-04-21 08:22:39 +09:00
kichikuou 6feab51a5d Update android/README.md 2025-04-10 10:45:14 +09:00
kichikuou 15d0b44ab9 Android: Move "Install from ZIP" to options menu and add help message
For consistency with xsystem4-android.
2025-04-10 10:12:56 +09:00
kichikuou a0f20caa77 Android: Support audio file names prefixed with track numbers 2025-04-10 10:12:56 +09:00
kichikuou 39712ee46e Version 2.14.3 2025-04-01 09:33:24 +09:00
kichikuou dcdbe7bb76 Android, Emscripten: Upgrade libwebp to 1.5.0 2025-04-01 09:28:33 +09:00
kichikuou 01a4255b83 Android: Upgrade SDL to 2.32.4 2025-04-01 08:49:30 +09:00
kichikuou d978a24a5e Fix build for big endian architectures 2025-04-01 08:24:42 +09:00
kichikuou ed196f72b9 Update game_compatibility.md
AliceNoir games are not supported.
2025-03-30 10:02:31 +09:00
kichikuou c9fd1dcfd0 Version 2.14.2 2025-03-09 13:44:58 +09:00
kichikuou c1018d9e0f Replace Color struct with SDL_Color 2025-03-09 13:16:02 +09:00
kichikuou cb8a48cdec Introduce sdl_palette
It replaces the sdl_col array and is set as the palette of main_surface.
2025-03-09 10:42:32 +09:00
kichikuou 6bf6a5c86a Delay mouse button state changes caused by touch events
This fixes #64 where a touch operation is recognized as a click in the
wrong position in Mamatoto.

This is the same problem that occured in xsystem4 and was addressed in
https://github.com/nunuhara/xsystem4/commit/5e80c9658787b118920f850ae4cbc883e6fceb1e,
and the fix is also the same.
2025-03-08 08:33:24 +09:00
kichikuou 790aa07130 Android: Upgrade AGP to 8.7.3 and bump minSdkVersion to 21
So that it builds with latest Android Studio.
2025-03-07 14:49:17 +09:00
kichikuou fa74a4744c Fix ags_scaledCopyArea() for 8-bit DIB
This fixes special move animation in Mamatoto.
2025-03-07 11:21:14 +09:00
kichikuou fb68b03a4f debugger: Update screen before entering REPL 2025-03-07 09:47:46 +09:00
kichikuou 75228cc4c8 Android: Back button to exit the game
Fixes #50.
2025-03-06 08:00:50 +09:00
kichikuou 8c13361164 emscripten: Use System3.9 compatible save format by default 2025-02-25 21:45:11 +09:00
kichikuou d05dc83e67 emscripten: Fix unused-function warning 2025-02-22 14:37:15 +09:00
kichikuou c9f21c4547 sactamask: Use sdl_effect framework 2025-02-21 09:14:05 +09:00
kichikuou f053f25397 Make webp_extract() return SDL_Surface instead of cgdata
This eliminates unnecessary RGBA -> RGB + alpha plane -> RGBA
conversion.
2025-02-21 09:14:02 +09:00
kichikuou f673708a3f Remove depth field from surface_t 2025-02-21 09:12:07 +09:00
kichikuou aab63adac2 Refactor image drawing functions 2025-02-21 09:10:55 +09:00
kichikuou 6f09a999d2 Gpx, ShGraph: Remove unused 16bpp surface support 2025-02-19 15:59:39 +09:00
kichikuou 2ed44dab6d Move surface and graphic functions from modules/lib to modules/Gpx
Except for gr_blend_alpha_map(), which is used by oujimisc.
2025-02-19 14:57:40 +09:00
kichikuou a8f46453d8 Remove redundant fields from surface_t 2025-02-19 14:03:01 +09:00
kichikuou baa4a3158f ags: Add ALPHA_AT macro 2025-02-19 13:39:20 +09:00
kichikuou 8328b93227 Rename agsurface_t to surface_t 2025-02-19 13:24:56 +09:00
kichikuou 6665416683 Refactor NightDemonDemo and tDemo to use SDL_Surface 2025-02-19 13:21:17 +09:00
kichikuou cf5e899632 Remove unused includes from NIGHTDLL/ and SACT/ 2025-02-19 12:38:47 +09:00
kichikuou 51954c6bd4 Move load_cg_to_sdlsurface() to src/cg.c
And rename it to cg_load_as_sdlsurface().
2025-02-19 12:30:13 +09:00
kichikuou f282c02376 Replace sf0 with main_surface 2025-02-19 12:15:10 +09:00
kichikuou e2c75fbd9d Rename sdl_dib to main_surface and move it to ags.h 2025-02-19 12:15:06 +09:00
kichikuou b28e3ef2fd Do not use gr_* functions from SACT/ and NIGHTDLL/ 2025-02-19 12:14:58 +09:00
kichikuou 215de5511e Simplify gre_BlendUseAMap() 2025-02-19 10:20:38 +09:00
kichikuou f669804573 Refactor sactamask.c to use SDL_Surface 2025-02-19 09:59:31 +09:00
kichikuou 9c6423bf99 drawtext: Remove 8-bit text rendering function 2025-02-19 09:59:22 +09:00
kichikuou 4f3b73c1ac Refactor sactlog.c 2025-02-19 08:21:50 +09:00
kichikuou 8ee53accf9 SACT: Change depth map from surface_t to SDL_Surface 2025-02-18 22:01:20 +09:00
kichikuou 6b646b3857 SACT: Change text canvas from surface_t to SDL_Surface 2025-02-18 22:01:18 +09:00
kichikuou dec1649882 SACT: Make sprites have SDL_Surface instead of surface_t 2025-02-18 21:58:06 +09:00
kichikuou 6b9c3475a0 Simplify sdl_scaledCopyArea() 2025-02-17 08:16:09 +09:00
kichikuou 1335a12065 Remove sp_draw2 2025-02-16 22:52:20 +09:00
kichikuou 93bd8ca737 sprite_sel.c: Remove unnecessary variable 2025-02-16 22:39:09 +09:00
kichikuou 5bae0c16c5 Simplify gr_ functions using SDL surface operations 2025-02-16 21:03:59 +09:00
kichikuou d551cdbb70 Refactor text rendering functions in modules/ 2025-02-16 13:13:16 +09:00
kichikuou e711d5786e Make agsurface_t backed by SDL_Surface
This adds `sdl_surface` field to agsurface_t. `agsurface->pixel` is now
set to `agsurfae->sdl_surface->pixels`.

Note that the `sdl_surface` field does not have alpha; transparent
surfaces have a separate alpha plane in `agsurface->alpha`.
2025-02-16 13:13:13 +09:00
kichikuou 64abb3c582 screenshot: Save only view area, not entire sdl_dib 2025-02-11 13:46:20 +09:00
kichikuou bf26f1b0c0 Refactor clipping functions 2025-02-11 12:36:21 +09:00
kichikuou f4f1a99372 Fix mathClip command 2025-02-11 12:36:18 +09:00
kichikuou 53f0a5ce2a sdl_effect: Fix palette issue when texture is created from sdl_dib 2025-02-11 10:30:25 +09:00
kichikuou c621a5dddb Remove intermediate screen buffer
Pixels are now copied directly from sdl_dib to sdl_texture.
2025-02-11 08:37:47 +09:00
kichikuou 42faf38a47 emscripten: Replace sdl_getDisplaySurface with save_screenshot function 2025-02-10 07:47:48 +09:00
202 changed files with 5630 additions and 13607 deletions
+4 -3
View File
@@ -15,7 +15,9 @@ jobs:
- sys: ucrt64
package: "xsystem35-64bit"
cmake_args: ""
deps: "cjson:p"
deps: >-
cjson:p
portmidi:p
defaults:
run:
shell: msys2 {0}
@@ -31,7 +33,6 @@ jobs:
SDL2_ttf:p
SDL2_mixer:p
libwebp:p
portmidi:p
${{ matrix.deps }}
- name: Checkout
@@ -42,7 +43,7 @@ jobs:
ls /${{ matrix.sys }}/share/licenses
mkdir dist
cp -r /${{ matrix.sys }}/share/licenses dist/
cp fonts/*.license dist/licenses/
cp licenses/* dist/licenses/
- name: Install dev dependencies
run: pacboy --noconfirm -S --needed gcc:p cmake:p ninja:p asciidoctor:p
+36 -2
View File
@@ -1,10 +1,44 @@
# Changelog
## 2.14.1 - 2024-02-07
## 2.17.1 - 2026-01-10
- Fixed an issue where Rance 5D could not save files on non-Windows systems.
- Improved fast-forward behavior using the Ctrl key in Rance 5D.
- The `SI 2` command now returns 0 if a playlist file is not provided.
## 2.17.0 - 2025-11-09
- Added "Streamer Mode" to mosaic specified (NSFW) images. This is enabled via the `-censor <file>` command-line option.
- Windows: Fixed an issue where Rance 5D could not save files if the `Save` directory did not exist.
## 2.16.1 - 2025-08-28
- Fixed text rendering issue in SACT log (#71)
- Windows: The 32-bit version no longer supports the portmidi MIDI backend
## 2.16.0 - 2025-06-13
- Fixed map tile color issue in Graymerca (#67)
- Windows: Implemented number input dialog for the `NI` command (#68)
- Android: Added "Clear Save Files" launcher menu command
## 2.15.1 - 2025-05-14
- Fixed a text rendering issue in Rance 5D (#66)
## 2.15.0 - 2025-04-21
- Fixed color palette bug introduced in v2.14.2.
- Fixed uncancellable message waiting mode.
- Android: "Install from ZIP" button is moved to the top-right option menu.
- Android: Improved extraction logic of track numbers from audio file names.
## 2.14.3 - 2025-04-01
- Fixed build for big endian architectures.
## 2.14.2 - 2025-03-09
- Android: Back button to exit the game (#50)
- Improved touch input usability in ママトト (#64)
## 2.14.1 - 2025-02-07
- Fixed font selection and text decoration not working in selection menus.
- Fixed a graphic issue in DALK intro.
## 2.14.0 - 2024-01-09
## 2.14.0 - 2025-01-09
- New supported games: 俺の下であがけ and 楽園行.
- Windows: On Windows 10 version 1903 or above, now xsystem35 can handle
Japanese filenames correctly even if the system locale is not Japanese.
+4 -9
View File
@@ -1,16 +1,11 @@
cmake_minimum_required(VERSION 3.13)
# Rebuild external projects when download URL changes
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0")
cmake_policy(SET CMP0135 NEW)
endif()
cmake_minimum_required(VERSION 3.13...4.0)
project(xsystem35 LANGUAGES C)
set(CMAKE_C_STANDARD 99)
enable_testing()
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)
set(XSYSTEM35_VERSION "2.14.1")
set(XSYSTEM35_VERSION "2.17.1")
include(CheckSymbolExists)
include(FetchContent)
@@ -37,8 +32,8 @@ endfunction()
function(fetch_webp)
FetchContent_Declare(
libwebp
URL https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.4.0.tar.gz
URL_HASH SHA1=0b1c8bea200caaa010182609dbaaa91aec69b64d
URL https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.5.0.tar.gz
URL_HASH SHA1=b21aa842136dc59a72a38776a5aa73f4d0b00ac5
)
set(WEBP_BUILD_ANIM_UTILS OFF CACHE BOOL "Build animation utilities." FORCE)
set(WEBP_BUILD_CWEBP OFF CACHE BOOL "Build the cwebp command line tool." FORCE)
+8
View File
@@ -60,6 +60,14 @@ and examine or modify game variables. There are two ways to use the debugger:
launch the debugger with a console interface. Type `help` to see a list of
available commands.
### Streamer Mode
xsystem35 introduces a "Streamer Mode" to make playing games with NSFW content
safer for streaming or public viewing. When enabled with the `-censor <file>`
option, images specified in the provided file will be automatically mosaiced.
The `misc/censor/` directory contains example censor list files for some games.
## Installation
Prebuilt packages for Windows and Android can be downloaded from the
+42 -34
View File
@@ -1,48 +1,25 @@
# xsystem35 for Android
Minimum supported Android version: 5.0
## Download
You can download prebuilt APKs
[here](https://github.com/kichikuou/xsystem35-sdl2/releases).
## Build
Prerequisites:
- Android SDK >=28
- Android NDK >=r15c
### Installing with Obtainium
Alternatively, you can install `xsystem35-sdl2` using [Obtainium](https://github.com/ImranR98/Obtainium). Obtainium will detect new releases and allow you to update the app directly.
### Using Android Studio
Open this directory as an Android Studio project.
1. Install Obtainium on your Android device.
2. Click the badge below to add the app to Obtainium:
### Command Line Build
Set environment variables and run the `gradlew` script in this directory.
Example build instructions (for Debian bookworm):
```sh
# Install necessary packages
sudo apt install git wget unzip default-jdk-headless ninja-build
# Install Android SDK / NDK
export ANDROID_SDK_ROOT=$HOME/android-sdk
mkdir -p $ANDROID_SDK_ROOT/cmdline-tools
wget https://dl.google.com/android/repository/commandlinetools-linux-10406996_latest.zip
unzip commandlinetools-linux-10406996_latest.zip -d $ANDROID_SDK_ROOT/cmdline-tools
mv $ANDROID_SDK_ROOT/cmdline-tools/cmdline-tools $ANDROID_SDK_ROOT/cmdline-tools/tools
yes | $ANDROID_SDK_ROOT/cmdline-tools/tools/bin/sdkmanager --licenses
$ANDROID_SDK_ROOT/cmdline-tools/tools/bin/sdkmanager ndk-bundle 'cmake;3.22.1'
export ANDROID_NDK_HOME=$ANDROID_SDK_ROOT/ndk-bundle
# Clone and build xsystem35
git clone https://github.com/kichikuou/xsystem35-sdl2.git
cd xsystem35-sdl2/android
./gradlew build # or ./gradlew installDebug if you have a connected device
```
[<img src="https://raw.githubusercontent.com/ImranR98/Obtainium/main/assets/graphics/badge_obtainium.png" alt="Get it on Obtainium" height="60">](https://apps.obtainium.imranr.dev/redirect?r=obtainium://app/%7B%22id%22%3A%22io.github.kichikuou.xsystem35%22%2C%22url%22%3A%22https%3A%2F%2Fgithub.com%2Fkichikuou%2Fxsystem35-sdl2%22%2C%22author%22%3A%22kichikuou%22%2C%22name%22%3A%22xsystem35%22%2C%22categories%22%3A%5B%22games%22%5D%7D)
## Usage
### Basic Usage
1. Create a ZIP file containing all the game files and BGM files (see
[below](#preparing-a-zip) for details), and transfer it to your device.
2. Open the app. A list of installed games will be displayed. Since no games
have been installed yet, only the "Install from ZIP" button will be visible.
Tap it.
2. Open the app. Tap the option menu (three dots in the top right corner) and
select "Install from ZIP".
3. Select the ZIP file you created in step 1.
4. The game will start. To simulate a right-click, tap the black bars on either
the left or right, or top or bottom of the screen.
@@ -51,10 +28,12 @@ cd xsystem35-sdl2/android
- Include all files from the `GAMEDATA` folder (such as `.ALD` files and
others). `.EXE` and `.DLL` files are not necessary, but you can include them
if you want.
- Music files (`.mp3`, `.ogg`, or `.wav`) whose filenames end with a number
will be recognized as BGM files. For example:
- Music files (`.mp3`, `.ogg`, or `.wav`) whose filenames have a number either
at the beginning or just before the extension are recognized as BGM files.
For example:
- `Track2.mp3`
- `15.ogg`
- `02 - Title.mp3`
- `rance4_03.wav` (Note: The filename shouldn't be `rance403.wav`, as it
would be treated as the 403rd track.)
@@ -71,3 +50,32 @@ Note: This ZIP format is also compatible with
[retroc.net](http://retropc.net/alice/). If you encounter the error message
"This type of ZIP is not supported," unzip the file on your PC and re-archive
it using modern ZIP creation software.
## Building from Source
### Using Android Studio
Open this directory as an Android Studio project.
### Command Line Build
Set environment variables and run the `gradlew` script in this directory.
Example build instructions (for Debian bookworm):
```sh
# Install necessary packages
sudo apt install git wget unzip default-jdk-headless ninja-build
# Install Android SDK / NDK
export ANDROID_SDK_ROOT=$HOME/android-sdk
mkdir -p $ANDROID_SDK_ROOT/cmdline-tools
wget https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip
unzip commandlinetools-linux-11076708_latest.zip -d $ANDROID_SDK_ROOT/cmdline-tools
mv $ANDROID_SDK_ROOT/cmdline-tools/cmdline-tools $ANDROID_SDK_ROOT/cmdline-tools/tools
yes | $ANDROID_SDK_ROOT/cmdline-tools/tools/bin/sdkmanager --licenses
$ANDROID_SDK_ROOT/cmdline-tools/tools/bin/sdkmanager ndk-bundle 'cmake;3.22.1'
export ANDROID_NDK_HOME=$ANDROID_SDK_ROOT/ndk-bundle
# Clone and build xsystem35
git clone https://github.com/kichikuou/xsystem35-sdl2.git
cd xsystem35-sdl2/android
./gradlew build # or ./gradlew installDebug if you have a connected device
```
+3 -3
View File
@@ -14,10 +14,10 @@ android {
}
compileSdkVersion 34
defaultConfig {
minSdkVersion 19
minSdkVersion 21
targetSdkVersion 34
versionCode 30
versionName "2.14.1" + gitRevision()
versionCode 36
versionName "2.17.1" + gitRevision()
externalNativeBuild {
cmake {
arguments "-DANDROID_APP_PLATFORM=android-19", "-DANDROID_STL=c++_static"
+5 -4
View File
@@ -7,8 +7,8 @@ set(PROJECT_ROOT_DIR ../../..)
include(FetchContent)
FetchContent_Declare(
SDL
URL https://github.com/libsdl-org/SDL/releases/download/release-2.30.12/SDL2-2.30.12.tar.gz
URL_HASH SHA1=36d48b045209dcd3576250c1571795ad0cd4d5a9
URL https://github.com/libsdl-org/SDL/releases/download/release-2.32.10/SDL2-2.32.10.tar.gz
URL_HASH SHA1=ce98fa93e31836a751feca374ab28a0770b63c16
)
FetchContent_Declare(
SDL_ttf
@@ -44,8 +44,9 @@ file(MAKE_DIRECTORY ${ASSETS_DIR}/licenses)
file(COPY_FILE ${PROJECT_ROOT_DIR}/fonts/MTLc3m.ttf ${ASSETS_DIR}/MTLc3m.ttf)
file(COPY_FILE ${PROJECT_ROOT_DIR}/fonts/mincho.otf ${ASSETS_DIR}/mincho.otf)
file(COPY_FILE ${PROJECT_ROOT_DIR}/COPYING ${ASSETS_DIR}/licenses/xsystem35)
file(COPY_FILE ${PROJECT_ROOT_DIR}/fonts/MTLc3m.ttf.license ${ASSETS_DIR}/licenses/MTLc3m)
file(COPY_FILE ${PROJECT_ROOT_DIR}/fonts/mincho.otf.license ${ASSETS_DIR}/licenses/mincho)
file(COPY_FILE ${PROJECT_ROOT_DIR}/licenses/MTLc3m.txt ${ASSETS_DIR}/licenses/MTLc3m)
file(COPY_FILE ${PROJECT_ROOT_DIR}/licenses/mincho.txt ${ASSETS_DIR}/licenses/mincho)
file(COPY_FILE ${PROJECT_ROOT_DIR}/licenses/nanojpeg.txt ${ASSETS_DIR}/licenses/nanojpeg)
file(COPY_FILE ${sdl_SOURCE_DIR}/LICENSE.txt ${ASSETS_DIR}/licenses/SDL)
file(COPY_FILE ${sdl_ttf_SOURCE_DIR}/LICENSE.txt ${ASSETS_DIR}/licenses/SDL_ttf)
file(COPY_FILE ${sdl_ttf_SOURCE_DIR}/external/freetype/docs/GPLv2.TXT ${ASSETS_DIR}/licenses/freetype)
+81
View File
@@ -15,3 +15,84 @@
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.SDLInputConnection {
void nativeCommitText(java.lang.String, int);
void nativeGenerateScancodeForUnichar(char);
}
-keep,includedescriptorclasses class org.libsdl.app.SDLActivity {
# for some reason these aren't compatible with allowoptimization modifier
boolean supportsRelativeMouse();
void setWindowStyle(boolean);
}
-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.SDLActivity {
java.lang.String nativeGetHint(java.lang.String); # Java-side doesn't use this, so it gets minified, but C-side still tries to register it
boolean onNativeSoftReturnKey();
void onNativeKeyboardFocusLost();
boolean isScreenKeyboardShown();
android.util.DisplayMetrics getDisplayDPI();
java.lang.String clipboardGetText();
boolean clipboardHasText();
void clipboardSetText(java.lang.String);
int createCustomCursor(int[], int, int, int, int);
void destroyCustomCursor(int);
android.content.Context getContext();
boolean getManifestEnvironmentVariables();
android.view.Surface getNativeSurface();
void initTouch();
boolean isAndroidTV();
boolean isChromebook();
boolean isDeXMode();
boolean isTablet();
void manualBackButton();
int messageboxShowMessageBox(int, java.lang.String, java.lang.String, int[], int[], java.lang.String[], int[]);
void minimizeWindow();
int openURL(java.lang.String);
void requestPermission(java.lang.String, int);
int showToast(java.lang.String, int, int, int, int);
boolean sendMessage(int, int);
boolean setActivityTitle(java.lang.String);
boolean setCustomCursor(int);
void setOrientation(int, int, boolean, java.lang.String);
boolean setRelativeMouseEnabled(boolean);
boolean setSystemCursor(int);
boolean shouldMinimizeOnFocusLoss();
boolean showTextInput(int, int, int, int);
}
-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.HIDDeviceManager {
boolean initialize(boolean, boolean);
boolean openDevice(int);
int sendOutputReport(int, byte[]);
int sendFeatureReport(int, byte[]);
boolean getFeatureReport(int, byte[]);
void closeDevice(int);
}
-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.SDLAudioManager {
int[] getAudioOutputDevices();
int[] getAudioInputDevices();
int[] audioOpen(int, int, int, int, int);
void audioWriteFloatBuffer(float[]);
void audioWriteShortBuffer(short[]);
void audioWriteByteBuffer(byte[]);
void audioClose();
int[] captureOpen(int, int, int, int, int);
int captureReadFloatBuffer(float[], boolean);
int captureReadShortBuffer(short[], boolean);
int captureReadByteBuffer(byte[], boolean);
void captureClose();
void audioSetThreadPriority(boolean, int);
native int nativeSetupJNI();
native void removeAudioDevice(boolean, int);
native void addAudioDevice(boolean, int);
}
-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.SDLControllerManager {
void pollInputDevices();
void pollHapticDevices();
void hapticRun(int, float, int);
void hapticStop(int);
}
@@ -127,6 +127,7 @@ class Launcher private constructor(private val rootDir: File) {
if (!saveDirFound) {
File(rootDir, SAVE_DIR).mkdir()
}
observer?.onGameListChange()
}
private fun createDirForGame(): File {
@@ -219,16 +220,17 @@ class Launcher private constructor(private val rootDir: File) {
var gameDir: String? = null
private set
private val aldRegex = """.*?s[a-z]\.ald""".toRegex(RegexOption.IGNORE_CASE)
private val audioRegex = """.*?(\d+)\.(wav|mp3|ogg)""".toRegex(RegexOption.IGNORE_CASE)
private val audioRegex = """((\d+).*|.*?(\d+))\.(wav|mp3|ogg)""".toRegex(RegexOption.IGNORE_CASE)
private val audioFiles: Array<String?> = arrayOfNulls(100)
fun maybeAdd(path: String) {
aldRegex.matchEntire(path)?.let {
val name = File(path).name
aldRegex.matchEntire(name)?.let {
gameDir = File(path).parent
ready = true
}
audioRegex.matchEntire(path)?.let {
val track = it.groupValues[1].toInt()
audioRegex.matchEntire(name)?.let {
val track = it.groupValues[2].toIntOrNull() ?: it.groupValues[3].toInt()
if (0 < track && track <= audioFiles.size)
audioFiles[track - 1] = path
}
@@ -251,6 +253,14 @@ class Launcher private constructor(private val rootDir: File) {
}
}
}
fun clearSaveData(): Boolean {
var success = true
File(rootDir, SAVE_DIR).listFiles()?.forEach { file ->
if (!file.deleteRecursively()) success = false
}
return success
}
}
private fun forEachZipEntry(input: InputStream, action: (ZipEntry, ZipInputStream) -> Unit): Boolean {
@@ -22,6 +22,7 @@ import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.provider.OpenableColumns
import android.text.Html
import android.util.Log
import android.view.Menu
import android.view.MenuItem
@@ -53,6 +54,8 @@ class LauncherActivity : Activity(), LauncherObserver {
onGameListChange()
val listView = findViewById<ListView>(R.id.list)
listView.emptyView = findViewById(R.id.empty)
findViewById<TextView>(R.id.usage).text = Html.fromHtml(getString(R.string.usage))
listView.setOnItemClickListener { _, _, position, _ ->
onListItemClick(position)
}
@@ -75,23 +78,15 @@ class LauncherActivity : Activity(), LauncherObserver {
}
private fun onListItemClick(position: Int) {
if (position < launcher.games.size) {
startGame(launcher.games[position].path, null)
} else {
val i = Intent(Intent.ACTION_GET_CONTENT)
i.type = CONTENT_TYPE_ZIP
startActivityForResult(Intent.createChooser(i, getString(R.string.choose_a_file)), INSTALL_REQUEST)
}
startGame(launcher.games[position].path, null)
}
private fun onItemLongClick(position: Int): Boolean {
if (position < launcher.games.size) {
AlertDialog.Builder(this).setTitle(R.string.uninstall_dialog_title)
.setMessage(getString(R.string.uninstall_dialog_message, launcher.games[position].title))
.setPositiveButton(R.string.ok) {_, _ -> uninstall(position)}
.setNegativeButton(R.string.cancel) {_, _ -> }
.show()
}
AlertDialog.Builder(this).setTitle(R.string.confirm)
.setMessage(getString(R.string.uninstall_dialog_message, launcher.games[position].title))
.setPositiveButton(R.string.ok) {_, _ -> uninstall(position)}
.setNegativeButton(R.string.cancel) {_, _ -> }
.show()
return true
}
@@ -102,6 +97,12 @@ class LauncherActivity : Activity(), LauncherObserver {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.install_from_zip -> {
val i = Intent(Intent.ACTION_GET_CONTENT)
i.type = CONTENT_TYPE_ZIP
startActivityForResult(Intent.createChooser(i, getString(R.string.choose_a_file)), INSTALL_REQUEST)
true
}
R.id.export_savedata -> {
val i = Intent(Intent.ACTION_CREATE_DOCUMENT)
i.type = CONTENT_TYPE_ZIP
@@ -116,6 +117,27 @@ class LauncherActivity : Activity(), LauncherObserver {
SAVEDATA_IMPORT_REQUEST)
true
}
R.id.clear_savedata -> {
AlertDialog.Builder(this)
.setTitle(R.string.confirm)
.setMessage(R.string.clear_save_data_confirm)
.setPositiveButton(R.string.ok) { _, _ ->
if (launcher.clearSaveData()) {
Toast.makeText(this, R.string.save_data_clear_success, Toast.LENGTH_SHORT).show()
} else {
errorDialog(R.string.save_data_clear_error)
}
}
.setNegativeButton(R.string.cancel, null)
.show()
true
}
R.id.help -> {
AlertDialog.Builder(this)
.setMessage(Html.fromHtml(getString(R.string.usage)))
.show()
true
}
R.id.licenses -> {
val intent = Intent(this, LicensesMenuActivity::class.java)
startActivity(intent)
@@ -157,7 +179,6 @@ class LauncherActivity : Activity(), LauncherObserver {
override fun onGameListChange() {
val items = launcher.titles.toMutableList()
items.add(getString(R.string.install_from_zip))
val listView = findViewById<ListView>(R.id.list)
listView.adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, items)
}
@@ -13,6 +13,7 @@ class LicensesMenuActivity : Activity() {
Entry("SDL", "SDL", "https://www.libsdl.org/"),
Entry("SDL_mixer", "SDL_mixer", "https://github.com/libsdl-org/SDL_mixer"),
Entry("SDL_ttf", "SDL_ttf", "https://github.com/libsdl-org/SDL_ttf"),
Entry("NanoJPEG", "nanojpeg", "https://keyj.emphy.de/nanojpeg/"),
Entry("FreeType", "freetype", "https://freetype.org/"),
Entry("HarfBuzz", "harfbuzz", "https://harfbuzz.github.io/"),
Entry("MotoyaLCedar W3 mono", "MTLc3m", "https://github.com/aosp-mirror/platform_frameworks_base/tree/lollipop-release/data/fonts"),
@@ -60,8 +60,8 @@ import java.util.Locale;
public class SDLActivity extends Activity implements View.OnSystemUiVisibilityChangeListener {
private static final String TAG = "SDL";
private static final int SDL_MAJOR_VERSION = 2;
private static final int SDL_MINOR_VERSION = 30;
private static final int SDL_MICRO_VERSION = 12;
private static final int SDL_MINOR_VERSION = 32;
private static final int SDL_MICRO_VERSION = 10;
/*
// Display InputType.SOURCE/CLASS of events and devices
//
@@ -790,6 +790,9 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
SDLActivity.mFullscreenModeActive = false;
}
if (Build.VERSION.SDK_INT >= 28 /* Android 9 (Pie) */) {
window.getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
}
}
} else {
Log.e(TAG, "error handling message, getContext() returned no Activity");
@@ -6,4 +6,12 @@
<ListView android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ScrollView android:id="@+id/empty"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:id="@+id/usage"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="20dp" />
</ScrollView>
</LinearLayout>
@@ -1,11 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/install_from_zip"
android:title="@string/action_install_from_zip" />
<item
android:id="@+id/export_savedata"
android:title="@string/action_export_save_data" />
<item
android:id="@+id/import_savedata"
android:title="@string/action_import_save_data" />
<item
android:id="@+id/clear_savedata"
android:title="@string/action_clear_save_data" />
<item
android:id="@+id/help"
android:title="@string/action_help" />
<item
android:id="@+id/licenses"
android:title="@string/action_licenses" />
+24 -2
View File
@@ -2,21 +2,43 @@
<resources>
<string name="app_name">xsystem35</string>
<string name="action_export_save_data">セーブデータをエクスポート</string>
<string name="action_help">使い方</string>
<string name="action_import_save_data">セーブデータをインポート</string>
<string name="action_install_from_zip">ZIPからインストール</string>
<string name="action_licenses">オープンソースライセンス</string>
<string name="action_clear_save_data">セーブデータをクリア</string>
<string name="cancel">キャンセル</string>
<string name="cannot_find_ald">System 3.x のファイル (*.ald) が見つかりません。</string>
<string name="choose_a_file">ファイルを選択</string>
<string name="clear_save_data_confirm">セーブデータをすべて削除します。元には戻せません。本当によろしいですか?</string>
<string name="confirm">確認</string>
<string name="error_dialog_title">エラー</string>
<string name="install_dialog_title">インストール中…</string>
<string name="install_from_zip">ZIP からインストール</string>
<string name="install_progress">%s を展開中</string>
<string name="no_data_to_import">ZIP アーカイブ中に save/ フォルダが見つかりません。</string>
<string name="save_data_export_error">セーブデータのエクスポートに失敗しました。</string>
<string name="save_data_export_success">エクスポートに成功しました。</string>
<string name="save_data_import_success">インポートに成功しました。</string>
<string name="save_data_clear_success">セーブデータをクリアしました。</string>
<string name="save_data_clear_error">セーブデータのクリアに失敗しました。</string>
<string name="uninstall_dialog_message">「%s」をアンインストールしますか?</string>
<string name="uninstall_dialog_title">確認</string>
<string name="unsupported_zip">この形式の ZIP はサポートしていません。</string>
<string name="zip_extraction_error">ZIP の展開に失敗しました。</string>
<string name="usage">
<![CDATA[
<h1>ゲームのインストール方法</h1>
<p>1. PC上で、ゲームのファイルが入ったZIPを用意します。例えば以下のようなファイルを含めます:</p>
<div>
・鬼畜王SA.ALD<br>
・鬼畜王GA.ALD<br>
・鬼畜王GB.ALD<br>
・鬼畜王WA.ALD<br>
・02.mp3<br>
・03.mp3<br>
・…<br>
</div>
<p>2. ZIPファイルを (例えばUSB経由で) PCからデバイスに転送します。</p>
<p>3. この画面の右上のメニューボタンをタップして「ZIPからインストール」を選択し、転送したZIPを選びます。</p>
]]>
</string>
</resources>
+25 -2
View File
@@ -1,22 +1,45 @@
<resources>
<string name="app_name">xsystem35</string>
<string name="action_clear_save_data">Clear Save Files</string>
<string name="action_export_save_data">Export Save Files</string>
<string name="action_help">Help</string>
<string name="action_import_save_data">Import Save Files</string>
<string name="action_install_from_zip">Install from ZIP</string>
<string name="action_licenses">Open source licenses</string>
<string name="cancel">Cancel</string>
<string name="cannot_find_ald">Cannot find System 3.x game files (*.ald).</string>
<string name="choose_a_file">Choose a file</string>
<string name="clear_save_data_confirm">Are you sure you want to clear all save files? This cannot be undone.</string>
<string name="confirm">Confirm</string>
<string name="error_dialog_title">Error</string>
<string name="install_dialog_title">Installing…</string>
<string name="install_from_zip">Install from ZIP</string>
<string name="install_progress">Extracting %s</string>
<string name="no_data_to_import">No save/ folder in the ZIP archive.</string>
<string name="ok">OK</string>
<string name="save_data_clear_error">Failed to clear save files.</string>
<string name="save_data_clear_success">Save files cleared.</string>
<string name="save_data_export_error">Failed to export save files.</string>
<string name="save_data_import_success">Imported successfully.</string>
<string name="save_data_export_success">Exported successfully.</string>
<string name="uninstall_dialog_message">Uninstall \"%s\"?</string>
<string name="uninstall_dialog_title">Confirm</string>
<string name="unsupported_zip">This type of ZIP is not supported.</string>
<string name="zip_extraction_error">Failed to extract ZIP.</string>
<string name="usage">
<![CDATA[
<h1>How to install a game</h1>
<p>1. On your PC, prepare a ZIP containing the game files. For example, it should contain the following files:</p>
<div>
* KICHIKUSA.ALD<br>
* KICHIKUGA.ALD<br>
* KICHIKUGB.ALD<br>
* KICHIKUWA.ALD<br>
* System39.ain<br>
* 02.mp3<br>
* 03.mp3<br>
* …<br>
</div>
<p>2. Transfer the ZIP file from your PC to the device (e.g. via USB).</p>
<p>3. Tap the menu button at the upper-right of this screen, select &quot;Install from ZIP,&quot; and choose the ZIP you transferred.</p>
]]>
</string>
</resources>
+1 -1
View File
@@ -7,7 +7,7 @@ buildscript {
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.1.1'
classpath 'com.android.tools.build:gradle:8.7.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
+1 -1
View File
@@ -1,6 +1,6 @@
#Thu Nov 11 18:20:34 PST 2021
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
+7 -1
View File
@@ -30,7 +30,8 @@ finds System 3.x game files (*.ALD) from the current directory.
*-game* _game_::
Enables game-specific hacks. Usually auto-detected, but must be specified for
games with modified / translated titles. Possible values are: `toushin2`,
`rance3_eng`, `rance4_eng`, `rance4_v2`, `persiom`, `agake`.
`rance2`, `rance3`, `rance3_eng`, `rance4_eng`, `rance4_v2`, `persiom`,
`agake`.
*-savedir* _dir_::
Directory to save game state files. If _dir_ begins with '~', it is expanded
@@ -48,6 +49,11 @@ finds System 3.x game files (*.ALD) from the current directory.
Suppress text hook on specified scenario pages. _list_ is a comma-separated
list of page numbers. Used to suppress system messages, etc.
*-censor* _file_::
Enable Streamer Mode, which mosaics specific images to make them safe for
streaming. The _file_ is a text file containing a list of image numbers
to censor, one per line. Lines starting with '#' are treated as comments.
*-renderer* _name_::
Use the SDL rendering driver named _name_.
-2
View File
@@ -1,8 +1,6 @@
install(FILES
MTLc3m.ttf
MTLc3m.ttf.license
mincho.otf
mincho.otf.license
DESTINATION share/xsystem35/fonts)
# pyftsubset is included in fonttools.
+2
View File
@@ -58,6 +58,8 @@ Game Compatibility
| 妻みぐい2 | Supported | |
| シェル・クレイル | Supported | |
| ナイトデーモン | Supported | |
| Nor | Unsupported | |
| 翡翠の眸 | Unsupported | |
| 学園KING | Supported | From アリスCD |
| 学園KING 番外編 | Supported | From アリスCD |
| 蒼海に墜ちて | Supported | From アリスCD |
+22
View File
@@ -0,0 +1,22 @@
// NanoJPEG -- KeyJ's Tiny Baseline JPEG Decoder
// version 1.3.5 (2016-11-14)
// Copyright (c) 2009-2016 Martin J. Fiedler <martin.fiedler@gmx.net>
// published under the terms of the MIT license
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
+21
View File
@@ -0,0 +1,21 @@
# Censor Lists for Streamer Mode
This directory contains sample censor lists for various games, intended for use
with xsystem35's Streamer Mode.
## Usage
To use a censor list, specify its path with the `-censor` command-line option
or in your `.xsys35rc` file. For example:
```bash
xsystem35 -censor misc/censor/kichikuou.txt
```
The list files contain image numbers (integers), one per line. Lines starting
with `#` are treated as comments.
## Contributing
We welcome contributions of censor lists for other games! If you have created
a censor list that you'd like to share, please open a Pull Request.
+164
View File
@@ -0,0 +1,164 @@
# Censor list for 鬼畜王ランス (Kichikuou Rance)
27
70
93
101
102
103
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
123
124
125
126
127
128
129
130
131
132
133
134
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
160
161
162
163
164
165
166
167
168
169
171
172
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
193
195
196
197
198
199
200
201
203
204
205
206
207
208
209
210
214
215
216
217
218
219
221
222
224
225
226
227
228
229
230
231
232
233
234
235
239
299
300
361
362
363
375
376
377
393
422
461
466
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
517
844
845
846
847
848
851
852
853
854
855
+5 -17
View File
@@ -5,7 +5,12 @@ add_library(modules STATIC
AliceLogo/AliceLogo.c
Confirm/Confirm.c
Gpx/Gpx.c
Gpx/cg.c
Gpx/effectcopy.c
Gpx/graph_copy_amap.c
Gpx/graph_fillrect_amap.c
Gpx/graph.c
Gpx/surface.c
Math/Math.c
MsgSkip/MsgSkip.c
NIGHTDLL/NIGHTDLL.c
@@ -61,25 +66,8 @@ add_library(modules STATIC
eeDemo/eeDemo.c
lib/alk.c
lib/drawtext.c
lib/graph.c
lib/list.c
lib/surface.c
lib/cg.c
lib/graph_expandcolor_blend.c
lib/graph_fillrect.c
lib/graph_fillrect_amap.c
lib/graph_fillrect_acolor.c
lib/graph_rect.c
lib/graph_copy.c
lib/graph_copy_amap.c
lib/graph_copy_bright.c
lib/graph_blend_amap.c
lib/graph_blend_screen.c
lib/graph_saturadd_amap.c
lib/graph_draw_amap.c
lib/graph_stretch.c
lib/graph_cg.c
lib/gre_blend_useamap.c
nDEMO/nDEMO.c
nDEMOE/nDEMOE.c
oDEMO/oDEMO.c
+13 -33
View File
@@ -42,7 +42,7 @@
// #include "alpha_plane.h"
#include "surface.h"
#include "graph.h"
// #include "graph2.h"
#include "graph_blend_amap.h"
#include "effectcopy.h"
#include "ngraph.h"
@@ -69,33 +69,17 @@ static int find_null_surface() {
}
static void sf_free_one(int no) {
surface_t *s;
if (no == 0) return;
s = suf[no];
if (s == NULL) return;
if (s->pixel) free(s->pixel);
if (s->alpha) free(s->alpha);
free(s);
if (no == 0 || !suf[no]) return;
sf_free(suf[no]);
suf[no] = NULL;
pre_freesurfno = no;
}
static void sf_free_all() {
int i;
surface_t *s;
for (i = 1; i < MAX_SURFACE; i++) {
if (suf[i] == NULL) continue;
s = suf[i];
if (s->pixel) free(s->pixel);
if (s->alpha) free(s->alpha);
free(s);
for (int i = 1; i < MAX_SURFACE; i++) {
sf_free(suf[i]);
suf[i] = NULL;
}
pre_freesurfno = 1;
}
@@ -149,18 +133,15 @@ static void Create() {
作成に失敗した場合は 0 を返す
width : surface の幅
height: surface の高さ
bpp : surface の深さ(オリジナルでは24bppのみサポート,
xsystem35 では display の depth と同じ)
bpp : surface の深さ(24bppのみサポート)
*/
int *var = getCaliVariable();
int width = getCaliValue();
int height = getCaliValue();
int bpp = getCaliValue();
surface_t *s;
//get_surface0();
s = sf_create_surface(width, height, sf_get(0)->depth);
surface_t *s = sf_create_surface(width, height);
if (s == NULL) {
*var = 0;
} else {
@@ -185,10 +166,9 @@ static void CreatePixelOnly() {
int width = getCaliValue();
int height = getCaliValue();
int bpp = getCaliValue();
surface_t *s;
s = sf_create_pixel(width, height, sf_get(0)->depth);
surface_t *s = sf_create_pixel(width, height);
if (s == NULL) {
*var = 0;
} else {
@@ -257,7 +237,7 @@ static void IsPixel() {
if (s == NULL) {
*var = 0;
} else {
*var = s->pixel ? 1 : 0;
*var = s->sdl_surface ? 1 : 0;
}
TRACE("Gpx.IsPixel %d,%p:", p1, var);
+20 -53
View File
@@ -33,9 +33,7 @@
#include "ags.h"
#include "pms.h"
#include "qnt.h"
#ifdef HAVE_WEBP
#include "webp.h"
#endif
#include "gfx.h"
#include "ngraph.h"
#include "dri.h"
#include "ald_manager.h"
@@ -53,10 +51,6 @@ static CG_TYPE check_cgformat(uint8_t *data) {
return ALCG_PMS8;
} else if (pms64k_checkfmt(data)) {
return ALCG_PMS16;
#ifdef HAVE_WEBP
} else if (webp_checkfmt(data)) {
return ALCG_WEBP;
#endif
}
return ALCG_UNKNOWN;
}
@@ -68,65 +62,38 @@ static CG_TYPE check_cgformat(uint8_t *data) {
* @return CG が展開された surface
* 未知の形式のときは NULL が返る
*/
surface_t *sf_getcg(void *b, size_t size) {
surface_t *sf = NULL;
int type;
cgdata *cg = NULL;
type = check_cgformat(b);
switch(type) {
static surface_t *sf_getcg(void *b, size_t size) {
surface_t *sf;
cgdata *cg;
switch(check_cgformat(b)) {
case ALCG_PMS8:
// Load as an alpha map
cg = pms256_extract(b);
cg->alpha = cg->pic;
cg->pic = NULL;
sf = sf_create_alpha(cg->width, cg->height);
gfx_drawImageAlphaMap(cg, sf, 0, 0);
break;
case ALCG_PMS16:
cg = pms64k_extract(b);
sf = cg->alpha
? sf_create_surface(cg->width, cg->height)
: sf_create_pixel(cg->width, cg->height);
gfx_drawImage16(cg, sf, 0, 0, 255, false);
break;
case ALCG_QNT:
cg = qnt_extract(b);
sf = cg->alpha
? sf_create_surface(cg->width, cg->height)
: sf_create_pixel(cg->width, cg->height);
gfx_drawImage24(cg, sf, 0, 0, 255);
break;
#ifdef HAVE_WEBP
case ALCG_WEBP:
cg = webp_extract(b, size);
break;
#endif
default:
break;
}
if (cg == NULL) {
WARNING("Unknown Cg Type");
return NULL;
}
switch(type) {
case ALCG_PMS8:
sf = sf_create_alpha(cg->width, cg->height);
gr_draw_amap(sf, cg->x, cg->y, cg->pic, cg->width, cg->height, cg->width);
break;
case ALCG_PMS16:
if (cg->alpha) {
sf = sf_create_surface(cg->width, cg->height, sf0->depth);
gr_drawimage16(sf, cg, cg->x, cg->y);
gr_draw_amap(sf, cg->x, cg->y, cg->alpha, cg->width, cg->height, cg->width);
} else {
sf = sf_create_pixel(cg->width, cg->height, sf0->depth);
gr_drawimage16(sf, cg, cg->x, cg->y);
}
break;
case ALCG_QNT:
case ALCG_WEBP:
if (cg->alpha) {
sf = sf_create_surface(cg->width, cg->height, sf0->depth);
gr_drawimage24(sf, cg, cg->x, cg->y);
gr_draw_amap(sf, cg->x, cg->y, cg->alpha, cg->width, cg->height, cg->width);
} else {
sf = sf_create_pixel(cg->width, cg->height, sf0->depth);
gr_drawimage24(sf, cg, cg->x, cg->y);
}
break;
}
cgdata_free(cg);
return sf;
}
+5 -5
View File
@@ -5,7 +5,7 @@
#include "portab.h"
#include "system.h"
#include "surface.h"
#include "sdl_core.h"
#include "effect.h"
#include "ags.h"
#include "input.h"
#include "graph.h"
@@ -24,17 +24,17 @@ void gpx_effect(int no,
*endtype = 0;
enum sdl_effect_type type = from_sact_effect(no);
enum effect_type type = from_sact_effect(no);
if (type == EFFECT_INVALID) {
WARNING("Unimplemented effect %d", no);
type = EFFECT_CROSSFADE;
}
SDL_Rect rect = { wx, wy, width, height };
struct sdl_effect *eff = sdl_effect_init(&rect, dst, dx, dy, src, sx, sy, type);
struct effect *eff = effect_init(&rect, dst, dx, dy, src, sx, sy, type);
if (!time)
time = (no == SACT_EFFECT_CROSSFADE_DOWN || no == SACT_EFFECT_CROSSFADE_UP) ? 1150 : 2700;
ags_runEffect(time, false, (ags_EffectStepFunc)sdl_effect_step, eff);
sdl_effect_finish(eff);
ags_runEffect(time, false, (ags_EffectStepFunc)effect_step, eff);
effect_finish(eff);
switch (no) {
case SACT_EFFECT_FADEOUT:
+81 -196
View File
@@ -3,25 +3,15 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <SDL.h>
#include "portab.h"
#include "system.h"
#include "surface.h"
#include "graph.h"
#include "ngraph.h"
#include "nact.h"
/*
gr_xxxx はクリッピングあり
gre_xxxx はクリッピングなし
*/
#undef WARNING
#define WARNING(...)
#undef NOTICE
#define NOTICE(...)
#include "ags.h"
#include "gfx.h"
/**
* surface から surface にコピーなどをする際に、転送元と転送先のsurface
@@ -42,74 +32,10 @@
* それぞれの引数は適宜変更されている
*/
bool gr_clip(surface_t *ss, int *sx, int *sy, int *sw, int *sh, surface_t *ds, int *dx, int *dy) {
int w, h;
if (ss == NULL) {
WARNING("ss surface is null");
return false;
}
if (ss == NULL) {
WARNING("ss surface is null");
return false;
}
if (*sx > ss->width) {
WARNING("sx is too large (sx=%d,width=%d)", *sx, ss->width);
return false;
}
if (*sy > ss->height) {
WARNING("sy is too large (sy=%d,height=%d)", *sy, ss->height);
return false;
}
if (*sx < 0) {
WARNING("sx is too small (sx=%d)", *sx);
return false;
}
if (*sy < 0) {
WARNING("sy is too small (sy=%d)", *sy);
return false;
}
if (*dx > ds->width) {
WARNING("dx is too large (dx=%d,width=%d)", *dx, ds->width);
return false;
}
if (*dy > ds->height) {
WARNING("dy is too large (dy=%d,height=%d)", *dy, ds->height);
return false;
}
w = *sw;
h = *sh;
if (*dx < 0) {
*sx -= *dx; *sw += *dx; *dx = 0;
}
if (*dy < 0) {
*sy -= *dy; *sh += *dy; *dy = 0;
}
*sw = min(ss->width - *sx, min(ds->width - *dx, *sw));
*sh = min(ss->height - *sy, min(ds->height - *dy, *sh));
if (*sw <= 0) {
WARNING("sw become <=0");
return false;
}
if (*sh <= 0) {
WARNING("sh become <=0");
return false;
}
if (*sw != w) {
NOTICE("width change %d -> %d", w, *sw);
}
if (*sh != h) {
NOTICE("height change %d -> %d", h, *sh);
}
return true;
if (!ss || !ds) return false;
SDL_Rect src_window = { 0, 0, ss->width, ss->height };
SDL_Rect dst_window = { 0, 0, ds->width, ds->height };
return ags_clipCopyRect(&src_window, &dst_window, sx, sy, dx, dy, sw, sh);
}
/**
@@ -126,88 +52,69 @@ bool gr_clip(surface_t *ss, int *sx, int *sy, int *sw, int *sh, surface_t *ds, i
* それぞれの引数は適宜変更されている
*/
bool gr_clip_xywh(surface_t *ss, int *sx, int *sy, int *sw, int *sh) {
int w, h;
if (ss == NULL) {
WARNING("ss surface is null");
if (!ss) return false;
SDL_Rect rect = {*sx, *sy, *sw, *sh};
if (!SDL_IntersectRect(&rect, &(SDL_Rect){ 0, 0, ss->width, ss->height }, &rect))
return false;
}
if (*sx > ss->width) {
WARNING("sx is too large (sx=%d,width=%d)", *sx, ss->width);
return false;
}
if (*sy > ss->height) {
WARNING("sy is too large (sy=%d,height=%d)", *sy, ss->height);
return false;
}
w = *sw;
h = *sh;
if (*sx < 0) {
*sw += *sx; *sx = 0;
}
if (*sy < 0) {
*sh += *sy; *sy = 0;
}
*sw = min(ss->width - *sx, *sw);
*sh = min(ss->height - *sy, *sh);
if (*sw <= 0) {
WARNING("sw become <=0");
return false;
}
if (*sh <= 0) {
WARNING("sh become <=0");
return false;
}
if (*sw != w) {
NOTICE("width change %d -> %d", w, *sw);
}
if (*sh != h) {
NOTICE("height change %d -> %d", h, *sh);
}
*sx = rect.x;
*sy = rect.y;
*sw = rect.w;
*sh = rect.h;
return true;
}
void gr_init() {
}
void gr_copy(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int sw, int sh) {
if (!dst->sdl_surface || !src->sdl_surface) return;
if (!gr_clip(src, &sx, &sy, &sw, &sh, dst, &dx, &dy)) return;
SDL_Rect src_rect = {sx, sy, sw, sh};
SDL_Rect dst_rect = {dx, dy, sw, sh};
if (dst == src) {
SDL_Rect r;
if (SDL_IntersectRect(&src_rect, &dst_rect, &r)) {
SDL_Surface *view = gfx_createSurfaceView(src->sdl_surface, sx, sy, sw, sh);
SDL_Surface *tmp = SDL_ConvertSurface(view, dst->sdl_surface->format, 0);
src_rect.x = 0;
src_rect.y = 0;
SDL_LowerBlit(tmp, &src_rect, dst->sdl_surface, &dst_rect);
SDL_FreeSurface(tmp);
SDL_FreeSurface(view);
return;
}
}
SDL_LowerBlit(src->sdl_surface, &src_rect, dst->sdl_surface, &dst_rect);
}
// Copy the specified surface area with brightness lv/255 times
void gr_copy_bright(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int width, int height, int lv) {
SDL_Rect src_rect = {sx, sy, width, height};
SDL_Rect dst_rect = {dx, dy, width, height};
SDL_SetSurfaceColorMod(src->sdl_surface, lv, lv, lv);
SDL_BlitSurface(src->sdl_surface, &src_rect, dst->sdl_surface, &dst_rect);
SDL_SetSurfaceColorMod(src->sdl_surface, 255, 255, 255);
}
void gr_fill(surface_t *dst, int dx, int dy, int dw, int dh, int r, int g, int b) {
SDL_Rect rect = {dx, dy, dw, dh};
uint32_t color = SDL_MapRGB(dst->sdl_surface->format, r, g, b);
SDL_FillRect(dst->sdl_surface, &rect, color);
}
void gr_copy_stretch(surface_t *dst, int dx, int dy, int dw, int dh, surface_t *src, int sx, int sy, int sw, int sh) {
SDL_Rect srcrect = {sx, sy, sw, sh};
SDL_Rect dstrect = {dx, dy, dw, dh};
SDL_BlitScaled(src->sdl_surface, &srcrect, dst->sdl_surface, &dstrect);
}
void gr_blend(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int width, int height, int lv) {
if (!gr_clip(src, &sx, &sy, &width, &height, dst, &dx, &dy)) return;
uint8_t *sp = GETOFFSET_PIXEL(src, sx, sy);
uint8_t *dp = GETOFFSET_PIXEL(dst, dx, dy);
switch(dst->depth) {
case 16:
for (int y = 0; y < height; y++) {
uint16_t *yls = (uint16_t *)(sp + y * src->bytes_per_line);
uint16_t *yld = (uint16_t *)(dp + y * dst->bytes_per_line);
for (int x = 0; x < width; x++) {
*yld = ALPHABLEND16(*yls, *yld, lv);
yls++; yld++;
}
}
break;
case 24:
case 32:
for (int y = 0; y < height; y++) {
uint32_t *yls = (uint32_t *)(sp + y * src->bytes_per_line);
uint32_t *yld = (uint32_t *)(dp + y * dst->bytes_per_line);
for (int x = 0; x < width; x++) {
*yld = ALPHABLEND24(*yls, *yld, lv);
yls++; yld++;
}
}
break;
}
SDL_SetSurfaceBlendMode(src->sdl_surface, SDL_BLENDMODE_BLEND);
SDL_SetSurfaceAlphaMod(src->sdl_surface, lv);
SDL_BlitSurface(src->sdl_surface, &(SDL_Rect){sx, sy, width, height}, dst->sdl_surface, &(SDL_Rect){dx, dy, width, height});
SDL_SetSurfaceAlphaMod(src->sdl_surface, 255);
SDL_SetSurfaceBlendMode(src->sdl_surface, SDL_BLENDMODE_NONE);
}
void gr_blend_src_bright(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int width, int height, int alpha, int rate) {
@@ -298,56 +205,34 @@ void gr_copy_stretch_blend_alpha_map(surface_t *dst, int dx, int dy, int dw, int
row[x] = xd; xd += a1;
}
switch(dst->depth) {
case 16:
{
uint16_t *yls, *yld;
uint8_t *yla;
for (y = 0; y < dh; y++) {
yls = (uint16_t *)(sp + *(y + col) * src->bytes_per_line);
yld = (uint16_t *)(dp + y * dst->bytes_per_line);
yla = (uint8_t *)(sa + *(y + col) * src->width);
for (x = 0; x < dw; x++) {
*(yld + x) = ALPHABLEND16(*(yls+ *(row + x)), *(yld+x), *(yla+*(row+x)));
}
while (y < dh - 1 && *(col + y) == *(col + y + 1)) {
yld += dst->width;
for (x = 0; x < dw; x++) {
*(yld + x) = ALPHABLEND16(*(yls+ *(row+x)), *(yld+x), *(yla+*(row+x)));
}
y++;
}
for (y = 0; y < dh; y++) {
uint32_t *yls = (uint32_t *)(sp + *(y + col) * src->sdl_surface->pitch);
uint32_t *yld = (uint32_t *)(dp + y * dst->sdl_surface->pitch);
uint8_t *yla = (uint8_t *)(sa + *(y + col) * src->width);
for (x = 0; x < dw; x++) {
*(yld + x) = ALPHABLEND24(*(yls+ *(row + x)), *(yld+x), *(yla+*(row+x)));
}
break;
}
case 24:
case 32:
{
uint32_t *yls, *yld;
uint8_t *yla;
for (y = 0; y < dh; y++) {
yls = (uint32_t *)(sp + *(y + col) * src->bytes_per_line);
yld = (uint32_t *)(dp + y * dst->bytes_per_line);
yla = (uint8_t *)(sa + *(y + col) * src->width);
while (y < dh - 1 && *(col + y) == *(col + y + 1)) {
yld += dst->width;
for (x = 0; x < dw; x++) {
*(yld + x) = ALPHABLEND24(*(yls+ *(row + x)), *(yld+x), *(yla+*(row+x)));
}
while (y < dh - 1 && *(col + y) == *(col + y + 1)) {
yld += dst->width;
for (x = 0; x < dw; x++) {
*(yld + x) = ALPHABLEND24(*(yls+ *(row+x)), *(yld+x), *(yla+*(row+x)));
}
y++;
*(yld + x) = ALPHABLEND24(*(yls+ *(row+x)), *(yld+x), *(yla+*(row+x)));
}
y++;
}
break;
}
}
free(row);
free(col);
}
// Fill the rectangle with the specified color (rgb) and blend rate (lv)
void gr_fill_alpha_color(surface_t *dst, int dx, int dy, int dw, int dh, int r, int g, int b, int lv) {
SDL_Surface *src = SDL_CreateRGBSurfaceWithFormat(0, dw, dh, 32, SDL_PIXELFORMAT_ARGB8888);
SDL_FillRect(src, NULL, SDL_MapRGBA(src->format, r, g, b, lv));
SDL_SetSurfaceBlendMode(src, SDL_BLENDMODE_BLEND);
SDL_Rect dstrect = {dx, dy, dw, dh};
SDL_BlitSurface(src, NULL, dst->sdl_surface, &dstrect);
SDL_FreeSurface(src);
}
#include "graph2.c"
+23
View File
@@ -0,0 +1,23 @@
#ifndef __GRAPH_H__
#define __GRAPH_H__
#include "config.h"
#include "surface.h"
void gr_init();
void gr_copy(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int sw, int sh);
void gr_copy_bright(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int width, int height, int lv);
void gr_fill(surface_t *dst, int dx, int dy, int dw, int dh, int r, int g, int b);
void gr_copy_stretch(surface_t *dst, int dx, int dy, int dw, int dh, surface_t *src, int sx, int sy, int sw, int sh);
void gr_blend(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int width, int height, int lv);
void gr_copy_stretch_blend_alpha_map(surface_t *dst, int dx, int dy, int dw, int dh, surface_t *src, int sx, int sy, int sw, int sh);
void gr_fill_alpha_color(surface_t *dst, int dx, int dy, int dw, int dh, int r, int g, int b, int lv);
void gr_fill_alpha_overborder(surface_t *dst, int dx, int dy, int dw, int dh, int s, int d);
void gr_fill_alpha_underborder(surface_t *dst, int dx, int dy, int dw, int dh, int s, int d);
void gr_copy_alpha_map_sprite(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int sw, int sh, int cl);
void gr_blend_alpha_wds_stretch2x2(surface_t *src1, int sx1, int sy1, surface_t *src2, int sx2, int sy2, int sw, int sh, surface_t *dst, int dx, int dy);
void gr_blend_alpha_wds(surface_t *src1, int sx1, int sy1, surface_t *src2, int sx2, int sy2, int sw, int sh, surface_t *dst, int dx, int dy);
#endif /* __GRAPH_H__ */
+9 -38
View File
@@ -75,7 +75,7 @@ void gr_copy_alpha_map_sprite(surface_t *dst, int dx, int dy, surface_t *src, in
}
void gr_blend_alpha_wds_stretch2x2(surface_t *src1, int sx1, int sy1, surface_t *src2, int sx2, int sy2, int sw, int sh, surface_t *dst, int dx, int dy) {
surface_t *t = sf_create_surface(sw * 2, sh * 2, dst->depth);
surface_t *t = sf_create_surface(sw * 2, sh * 2);
gr_copy_stretch(t, 0, 0, sw * 2, sh * 2, src2, sx2, sy2, sw, sh);
gr_blend_alpha_wds(t, 0, 0, src1, sx1, sy1, sw * 2, sh * 2, dst, dx, dy);
@@ -93,45 +93,16 @@ void gr_blend_alpha_wds(surface_t *src1, int sx1, int sy1, surface_t *src2, int
sa = GETOFFSET_ALPHA(src1, sx1, sy1);
dp = GETOFFSET_PIXEL(dst, dx, dy);
switch(dst->depth) {
case 16:
{
uint16_t *yls1, *yls2, *yld;
uint8_t *yla;
for (y = 0; y < sh; y++) {
yls1 = (uint16_t *)(sp1 + y * src1->bytes_per_line);
yls2 = (uint16_t *)(sp2 + y * src2->bytes_per_line);
yld = (uint16_t *)(dp + y * dst->bytes_per_line);
yla = (uint8_t *)(sa + y * src1->width);
for (x = 0; x < sw; x++) {
*yld = SUTURADD16(*yls1, ALPHABLEND16(*yls1, *yls2, *yla));
//*yld = SUTURADD16(*yls1, ALPHALEVEL16(*yls2, *yla));
yls1++; yls2++; yld++; yla++;
}
}
}
break;
case 24:
case 32:
{
uint32_t *yls1, *yls2, *yld;
uint8_t *yla;
for (y = 0; y < sh; y++) {
uint32_t *yls1 = (uint32_t *)(sp1 + y * src1->sdl_surface->pitch);
uint32_t *yls2 = (uint32_t *)(sp2 + y * src2->sdl_surface->pitch);
uint32_t *yld = (uint32_t *)(dp + y * dst->sdl_surface->pitch);
uint8_t *yla = (uint8_t *)(sa + y * src1->width);
for (y = 0; y < sh; y++) {
yls1 = (uint32_t *)(sp1 + y * src1->bytes_per_line);
yls2 = (uint32_t *)(sp2 + y * src2->bytes_per_line);
yld = (uint32_t *)(dp + y * dst->bytes_per_line);
yla = (uint8_t *)(sa + y * src1->width);
for (x = 0; x < sw; x++) {
*yld = SUTURADD24(*yls1, ALPHABLEND24(*yls1, *yls2, *yla));
yls1++; yls2++; yld++; yla++;
}
for (x = 0; x < sw; x++) {
*yld = SUTURADD24(*yls1, ALPHABLEND24(*yls1, *yls2, *yla));
yls1++; yls2++; yld++; yla++;
}
break;
}
}
}
+33
View File
@@ -0,0 +1,33 @@
#ifndef __NGRAPH_H__
#define __NGRAPH_H__
#include "portab.h"
#include "nact.h"
#include "ags.h"
#include "surface.h"
#include "graph.h"
#define sf0 nact->ags.dib
struct SDL_Surface;
// DLL 用 graphic 関連関数
/* in graph.c */
bool gr_clip(surface_t *ss, int *sx, int *sy, int *sw, int *sh, surface_t *ds, int *dx, int *dy);
bool gr_clip_xywh(surface_t *ss, int *sx, int *sy, int *sw, int *sh);
/* in graph_fillrect_amap.c */
void gr_fill_alpha_map(surface_t *dst, int dx, int dy, int dw, int dh, int lv);
/* in graph_copy_amap.c */
void gr_copy_alpha_map(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int sw, int sh);
// /* in graph_bright_dst_only.c */
#define gr_bright_dst_only(dst,dx,dy,w,h,lv) gr_copy_bright(dst,dx,dy,dst,dx,dy,w,h,lv)
// void gr_bright_dst_only(surface_t *dst, int dx, int dy, int w, int h, int lv);
/* defined in cg.c */
surface_t *sf_loadcg_no(int no);
#endif /* __GRAPH_H__ */
+80
View File
@@ -0,0 +1,80 @@
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <SDL.h>
#include "portab.h"
#include "surface.h"
#include "system.h"
static surface_t *create(int width, int height, bool has_pixel, bool has_alpha) {
surface_t *s = calloc(1, sizeof(surface_t));
s->width = width;
s->height = height;
if (has_pixel) {
s->sdl_surface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 32, SDL_PIXELFORMAT_RGB888);
}
if (has_alpha) {
s->alpha = calloc(width * (height +1), sizeof(uint8_t));
}
return s;
}
// Create a surface with pixel and alpha data
surface_t *sf_create_surface(int width, int height) {
return create(width, height, true, true);
}
// Create a surface with alpha data only
surface_t *sf_create_alpha(int width, int height) {
return create(width, height, false, true);
}
// Create a surface with pixel data only
surface_t *sf_create_pixel(int width, int height) {
return create(width, height, true, false);
}
/**
* surfaceオブジェクトの開放
* @param s: 開放するオブジェクト
* @return: なし
*/
void sf_free(surface_t *s) {
if (s == NULL) return;
if (s->sdl_surface) SDL_FreeSurface(s->sdl_surface);
if (s->alpha) free(s->alpha);
free(s);
}
/**
* surface の複製を作成(dupulicate)
* @param in: 複製もと
* @return : 複製したsurface
*/
surface_t *sf_dup(surface_t *in) {
surface_t *sf;
int len;
if (in == NULL) return NULL;
sf = malloc(sizeof(surface_t));
memcpy(sf, in, sizeof(surface_t));
if (in->sdl_surface) {
sf->sdl_surface = SDL_ConvertSurface(in->sdl_surface, in->sdl_surface->format, 0);
}
if (in->alpha) {
len = sf->width * sf->height;
sf->alpha = malloc(sizeof(uint8_t) * (len + sf->width));
memcpy(sf->alpha, in->alpha, len);
}
return sf;
}
+13
View File
@@ -0,0 +1,13 @@
#ifndef __SURFACE_H__
#define __SURFACE_H__
#include "portab.h"
#include "ags.h"
extern surface_t *sf_create_surface(int width, int height);
extern surface_t *sf_create_alpha(int width, int height);
extern surface_t *sf_create_pixel(int width, int height);
extern void sf_free(surface_t *s);
extern surface_t *sf_dup(surface_t *in);
#endif /* __SURFACE_H__ */
+1 -3
View File
@@ -3,8 +3,6 @@
#include "config.h"
#include "portab.h"
#include "graphics.h"
#include "surface.h"
#include "ags.h"
#include "sprite.h"
@@ -43,7 +41,7 @@ struct _night {
// graph
// cginfo_t *cg[CGMAX];
MyRectangle updaterect;
SDL_Rect updaterect;
FontType fonttype;
int fontsize;
+8 -16
View File
@@ -1,12 +1,10 @@
#include <stdio.h>
#include <SDL.h>
#include "portab.h"
#include "system.h"
#include "cg.h"
#include "ags.h"
#include "surface.h"
#include "graph.h"
#include "ngraph.h"
#include "night.h"
#include "sprite.h"
#include "nt_scenario.h"
@@ -55,8 +53,8 @@ void nt_gr_set_wallpaper(int no) {
sp = nt_sp_new(SPNO_WALL, no, 0, 0, SPRITE_WP);
nt_sp_add_updatelist(sp);
if (no == 0) {
sp->cursize.width = sf0->width;
sp->cursize.height = sf0->height;
sp->width = main_surface->w;
sp->height = main_surface->h;
sp->update = nt_sp_draw_wall;
}
@@ -192,15 +190,9 @@ void nt_gr_draw(int effectno) {
}
void nt_gr_screencg(int no, int x, int y) {
surface_t *sf;
sf = sf_loadcg_no(no -1);
gr_blend_screen(sf0, x, y, sf, 0, 0, sf->width, sf->height);
ags_updateArea(x, y, sf->width, sf->height);
sf_free(sf);
SDL_Surface *sf = cg_load_as_sdlsurface(no - 1);
SDL_SetSurfaceBlendMode(sf, SDL_BLENDMODE_ADD);
SDL_BlitSurface(sf, NULL, main_surface, &(SDL_Rect){x, y, sf->w, sf->h});
ags_updateArea(x, y, sf->w, sf->h);
SDL_FreeSurface(sf);
}
+60 -81
View File
@@ -3,15 +3,14 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <SDL.h>
#include "portab.h"
#include "system.h"
#include "sdl_core.h"
#include "utfsjis.h"
#include "ags.h"
#include "nact.h"
#include "input.h"
#include "ngraph.h"
#include "drawtext.h"
#include "night.h"
#include "nt_msg.h"
@@ -25,23 +24,29 @@ extern int ntsel_dosel(void);
#define SNAME_RYO "亮    "
#define SNAME_RYO_DEF "亮"
// 通常メッセージ表示位置と大きさ
#define MSGFRAME_0_X 6
#define MSGFRAME_0_Y 347
#define MSGFRAME_0_WIDTH 628
#define MSGFRAME_0_HEIGHT 125
// Normal message window
static const SDL_Rect msgframe_0 = {
.x = 6,
.y = 347,
.w = 628,
.h = 125
};
// 画面全体メッセージ表示位置と大きさ
#define MSGFRAME_1_X 0
#define MSGFRAME_1_Y 0
#define MSGFRAME_1_WIDTH 640
#define MSGFRAME_1_HEIGHT 480
// Full screen message window
static const SDL_Rect msgframe_1 = {
.x = 0,
.y = 0,
.w = 640,
.h = 480
};
// 通常メッセージ(顔つき)表示位置と大きさ
#define MSGFRAME_2_X (6+160)
#define MSGFRAME_2_Y 347
#define MSGFRAME_2_WIDTH (628-160)
#define MSGFRAME_2_HEIGHT 125
// Normal message (with face) window
static const SDL_Rect msgframe_2 = {
.x = 6 + 160,
.y = 347,
.w = 628 - 160,
.h = 125
};
// キー入力アニメーション位置
#define HAKANIM_LOC_X 620
@@ -69,7 +74,7 @@ void ntmsg_init() {
sprite_t *sp;
// メッセージスプライト
sp = night.sp[SPNO_MSGFRAME_FG] = nt_sp_msg_new(SPNO_MSGFRAME_FG, 0, 0, sf0->width, sf0->height);
sp = night.sp[SPNO_MSGFRAME_FG] = nt_sp_msg_new(SPNO_MSGFRAME_FG, 0, 0, main_surface->w, main_surface->h);
nt_sp_add_updatelist(sp);
// メッセージ背景用CG
@@ -78,7 +83,7 @@ void ntmsg_init() {
// 文字背景CG作成
nt_scg_create(CGNO_MSGFR_BG,
sf0->width, sf0->height,
main_surface->w, main_surface->h,
0, 0, 0, 255);
// night.cg[CGNO_MSGFR_BG]->refcnt++;
@@ -121,13 +126,10 @@ void ntmsg_init() {
// type=1 枠あり
// type=2 中央
void ntmsg_set_frame(int type) {
surface_t *sf;
night.msgframe = type;
sf = night.sp[SPNO_MSGBG]->curcg->sf;
memset(sf->pixel, 0, sf->bytes_per_line * sf->height);
memset(sf->alpha, 0, sf->width * sf->height);
SDL_Surface *sf = night.sp[SPNO_MSGBG]->curcg->sf;
SDL_FillRect(sf, NULL, 0);
switch(type) {
case 0:
@@ -140,11 +142,7 @@ void ntmsg_set_frame(int type) {
nt_sp_set_show(night.sp[SPNO_MSGFRAME_BG], true);
nt_sp_set_show(night.sp[SPNO_MSGFRAME_FG], true);
gr_fill(sf, MSGFRAME_0_X, MSGFRAME_0_Y,
MSGFRAME_0_WIDTH, MSGFRAME_0_HEIGHT,
16, 32, 64);
gr_fill_alpha_map(sf, MSGFRAME_0_X, MSGFRAME_0_Y,
MSGFRAME_0_WIDTH, MSGFRAME_0_HEIGHT, 192);
SDL_FillRect(sf, &msgframe_0, SDL_MapRGBA(sf->format, 16, 32, 64, 192));
ntmsg_clear(SPNO_MSGFRAME_FG);
nt_sp_update_all(true);
break;
@@ -153,11 +151,7 @@ void ntmsg_set_frame(int type) {
nt_sp_set_show(night.sp[SPNO_MSGFRAME_BG], false);
nt_sp_set_show(night.sp[SPNO_MSGFRAME_FG], true);
gr_fill(sf, MSGFRAME_1_X, MSGFRAME_1_Y,
MSGFRAME_1_WIDTH, MSGFRAME_1_HEIGHT,
32, 32, 32);
gr_fill_alpha_map(sf, MSGFRAME_1_X, MSGFRAME_1_Y,
MSGFRAME_1_WIDTH, MSGFRAME_1_HEIGHT, 128);
SDL_FillRect(sf, &msgframe_1, SDL_MapRGBA(sf->format, 32, 32, 32, 128));
ntmsg_clear(SPNO_MSGFRAME_FG);
nt_sp_update_all(true);
@@ -222,7 +216,7 @@ static void ntmsg_out(int wNum, int wSize, int wColorR, int wColorG, int wColorB
char *msg;
sprite_t *sp;
bool needupdate = false;
MyRectangle uparea = {0,0,0,0};
SDL_Rect uparea = {0,0,0,0};
int savex;
if (night.msgbuf[0] == '\0') return;
@@ -241,7 +235,7 @@ static void ntmsg_out(int wNum, int wSize, int wColorR, int wColorG, int wColorB
char mbuf[20];
int cw, delta, wcnt;
wcnt = sdl_getTicks();
wcnt = sys_get_ticks();
mbuf[0] = '\0';
msg = get_char(msg, mbuf, sizeof(mbuf) -1);
@@ -272,7 +266,7 @@ static void ntmsg_out(int wNum, int wSize, int wColorR, int wColorG, int wColorB
needupdate = false;
// keywait
delta = sdl_getTicks() - wcnt;
delta = sys_get_ticks() - wcnt;
if (delta < wSpeed) {
if (sys_keywait(wSpeed - delta, KEYWAIT_NONCANCELABLE)) {
@@ -289,8 +283,8 @@ static void ntmsg_out(int wNum, int wSize, int wColorR, int wColorG, int wColorB
// Waitなしの出力は最後にupdate
if (needupdate) {
uparea.w = sp->cursize.width;
uparea.h = min(sp->cursize.height, uparea.y - sp->u.msg.dspcur.y + wLineSpace + wLineSpace);
uparea.w = sp->width;
uparea.h = min(sp->height, uparea.y - sp->u.msg.dspcur.y + wLineSpace + wLineSpace);
nt_sp_updateme_part(sp, uparea.x, uparea.y, uparea.w, uparea.h);
}
@@ -316,14 +310,14 @@ static int ntmsg_keywait() {
night.waitkey = -1;
while (night.waitkey == -1 && !nact->is_quit) {
int st = sdl_getTicks();
int st = sys_get_ticks();
int interval = 25;
if (!night.zhiding) {
interval = night.sp[SPNO_MSG_KEYANIM]->u.anime.interval;
hakanim(i++);
}
sys_keywait(interval - (sdl_getTicks() - st), KEYWAIT_NONCANCELABLE);
sys_keywait(interval - (sys_get_ticks() - st), KEYWAIT_NONCANCELABLE);
}
night.waittype = KEYWAIT_NONE;
@@ -337,8 +331,8 @@ static void set_align(char *msg, sprite_t *sp, int wSize) {
switch(night.msgplace) {
case 0:
sp->u.msg.dspcur.x = MSGFRAME_0_X;
sp->u.msg.dspcur.y = MSGFRAME_0_Y + 8;
sp->u.msg.dspcur.x = msgframe_0.x;
sp->u.msg.dspcur.y = msgframe_0.y + 8;
break;
case 1:
@@ -360,12 +354,12 @@ static void set_align(char *msg, sprite_t *sp, int wSize) {
maxchar = max(maxchar, c);
line++;
sp->u.msg.dspcur.x = (sp->cursize.width - (maxchar * wSize/2)) /2;
sp->u.msg.dspcur.y = (sp->cursize.height - (line * (wSize+2))) /2;
sp->u.msg.dspcur.x = (sp->width - (maxchar * wSize/2)) /2;
sp->u.msg.dspcur.y = (sp->height - (line * (wSize+2))) /2;
break;
case 2:
sp->u.msg.dspcur.x = MSGFRAME_2_X;
sp->u.msg.dspcur.y = MSGFRAME_2_Y + 8;
sp->u.msg.dspcur.x = msgframe_2.x;
sp->u.msg.dspcur.y = msgframe_2.y + 8;
break;
}
@@ -441,51 +435,36 @@ static void hakanim(int i) {
sp->show = show;
}
void ntmsg_update(sprite_t *sp, MyRectangle *r) {
int sx, sy, w, h, dx, dy;
surface_t update;
// canvas が clean のときはなにもしない
// -> 説明スプライトのように、SetShowされたときに対応できないからだめ
//if (sact.msgbufempty) return;
update.width = r->w;
update.height = r->h;
dx = sp->cur.x - r->x;
dy = sp->cur.y - r->y;
w = sp->cursize.width;
h = sp->cursize.height;
sx = 0; sy = 0;
if (!gr_clip(sp->u.msg.canvas, &sx, &sy, &w, &h, &update, &dx, &dy)) {
void ntmsg_update(sprite_t *sp, SDL_Rect *r) {
SDL_Rect sp_rect = {0, 0, sp->width, sp->height};
int sx = 0;
int sy = 0;
int dx = sp->cur.x;
int dy = sp->cur.y;
int w = sp->width;
int h = sp->height;
if (!ags_clipCopyRect(&sp_rect, r, &sx, &sy, &dx, &dy, &w, &h)) {
return;
}
dx += r->x;
dy += r->y;
gre_BlendUseAMap(sf0, dx, dy, sf0, dx, dy, sp->u.msg.canvas, sx, sy, w, h, sp->u.msg.canvas, sx, sy, sp->blendrate);
SDL_SetSurfaceBlendMode(sp->u.msg.canvas, SDL_BLENDMODE_BLEND);
SDL_SetSurfaceAlphaMod(sp->u.msg.canvas, sp->blendrate);
SDL_BlitSurface(sp->u.msg.canvas, &(SDL_Rect){sx, sy, w, h}, main_surface, &(SDL_Rect){dx, dy, w, h});
SACT_DEBUG("do update no=%d, sx=%d, sy=%d, w=%d, h=%d, dx=%d, dy=%d",
sp->no, sx, sy, w, h, dx, dy);
}
static void ntmsg_clear(int wNum) {
sprite_t *sp = night.sp[wNum];
surface_t *sf;
sp->u.msg.dspcur.x = 0;
sp->u.msg.dspcur.y = 0;
night.msgbuf[0] = '\0';
// キャンバスのクリア
sf = sp->u.msg.canvas;
memset(sf->pixel, 0, sf->bytes_per_line * sf->height);
memset(sf->alpha, 0, sf->width * sf->height);
// Clear the canvas
SDL_FillRect(sp->u.msg.canvas, NULL, 0);
nt_sp_updateme(sp);
}
+1 -1
View File
@@ -7,6 +7,6 @@ void ntmsg_set_place(int type);
void ntmsg_newline();
void ntmsg_add(const char *msg);
int ntmsg_ana(void);
void ntmsg_update(sprite_t *sp, MyRectangle *r);
void ntmsg_update(sprite_t *sp, SDL_Rect *r);
#endif /* __NT_MSG_H__ */
-1
View File
@@ -8,7 +8,6 @@
#include "portab.h"
#include "system.h"
#include "input.h"
#include "sdl_core.h"
#include "scheduler.h"
#include "xsystem35.h"
#include "nact.h"
+9 -20
View File
@@ -26,29 +26,25 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <SDL.h>
#include "portab.h"
#include "nact.h"
#include "system.h"
#include "ags.h"
#include "surface.h"
#include "ngraph.h"
#include "cg.h"
#include "sactcg.h"
#define CGMAX 65536
static cginfo_t *cgs[CGMAX];
#include "sactcg_stretch.c"
#include "sactcg_blend.c"
#define SPCG_ASSERT_NO(no) \
if ((no) > (CGMAX -1)) { \
WARNING("no is too large (should be %d < %d)", (no), CGMAX); \
return; \
} \
static cginfo_t *nt_scg_new(enum cgtype type, int no, surface_t *sf) {
static cginfo_t *nt_scg_new(enum cgtype type, int no, SDL_Surface *sf) {
cginfo_t *info = calloc(1, sizeof(cginfo_t));
info->type = type;
info->no = no;
@@ -78,7 +74,7 @@ static cginfo_t *nt_scg_get(int no) {
if (cgs[no] != NULL)
return cgs[no];
surface_t *sf = sf_loadcg_no(no - 1);
SDL_Surface *sf = cg_load_as_sdlsurface(no - 1);
if (!sf) {
WARNING("load fail (%d)", no -1);
return NULL;
@@ -98,7 +94,7 @@ void nt_scg_deref(cginfo_t *cg) {
return;
if (cg->sf)
sf_free(cg->sf);
SDL_FreeSurface(cg->sf);
free(cg);
}
@@ -106,9 +102,8 @@ void nt_scg_deref(cginfo_t *cg) {
void nt_scg_create(int wNumCG, int wWidth, int wHeight, int wR, int wG, int wB, int wBlendRate) {
SPCG_ASSERT_NO(wNumCG);
surface_t *sf = sf_create_surface(wWidth, wHeight, sf0->depth);
gr_fill(sf, 0, 0, wWidth, wHeight, wR, wG, wB);
gr_fill_alpha_map(sf, 0, 0, wWidth, wHeight, wBlendRate);
SDL_Surface *sf = SDL_CreateRGBSurfaceWithFormat(0, wWidth, wHeight, 32, SDL_PIXELFORMAT_ARGB8888);
SDL_FillRect(sf, NULL, SDL_MapRGBA(sf->format, wR, wG, wB, wBlendRate));
nt_scg_new(CG_SET, wNumCG, sf);
}
@@ -121,14 +116,8 @@ void nt_scg_cut(int wNumDstCG, int wNumSrcCG, int wX, int wY, int wWidth, int wH
if (!src)
return;
surface_t *sf = src->sf->alpha
? sf_create_surface(wWidth, wHeight, src->sf->depth)
: sf_create_pixel(wWidth, wHeight, src->sf->depth);
if (src->sf->pixel)
gr_copy(sf, 0, 0, src->sf, wX, wY, wWidth, wHeight);
if (src->sf->alpha)
gr_copy_alpha_map(sf, 0, 0, src->sf, wX, wY, wWidth, wHeight);
SDL_Surface *sf = SDL_CreateRGBSurfaceWithFormat(0, wWidth, wHeight, src->sf->format->BitsPerPixel, src->sf->format->format);
SDL_BlitSurface(src->sf, &(SDL_Rect){wX, wY, wWidth, wHeight}, sf, NULL);
nt_scg_new(CG_SET, wNumDstCG, sf);
}
-31
View File
@@ -1,31 +0,0 @@
//
static surface_t *blend(surface_t *base, int x, int y, surface_t *blend, int mode) {
surface_t *dst = sf_create_surface(base->width, base->height, base->depth);
gr_copy(dst, 0, 0, base, 0, 0, base->width, base->height);
if (base->alpha) {
// ベースに alpha map がある場合はそれをコピー
gr_copy_alpha_map(dst, 0, 0, base, 0, 0, base->width, base->height);
} else {
// 無い場合は全て 255 の map を作成
gr_fill_alpha_map(dst, 0, 0, base->width, base->height, 255);
}
if (blend->alpha) {
// 重ね合わせ先の alpha map があるときはそれを使う
gre_BlendUseAMap(dst, x, y, base, x, y, blend, 0, 0, blend->width, blend->height, blend, 0, 0, 255);
} else {
// 無いときは dst の alpha map を使う
gre_BlendUseAMap(dst, x, y, base, x, y, blend, 0, 0, blend->width, blend->height, dst, x, y, 255);
}
// alpha 作成モードが dst + blend の時は飽和加算
if (mode == 1) {
gr_saturadd_alpha_map(dst, x, y, blend, 0, 0, blend->width, blend->height);
}
return dst;
}
-114
View File
@@ -1,114 +0,0 @@
// 拡大縮小
static surface_t *stretch(surface_t *src, int dw, int dh, int mirror) {
surface_t *dst = calloc(1, sizeof(surface_t));
float a1, a2, xd, yd;
int sw, sh;
int *row, *col;
int x, y;
uint8_t *sdata, *ddata;
dst->width = dw;
dst->height = dh;
dst->depth = src->depth;
dst->bytes_per_line = dw * src->bytes_per_pixel;
dst->bytes_per_pixel = src->bytes_per_pixel;
if (src->pixel) {
dst->pixel = malloc(dh * dst->bytes_per_line);
}
if (src->alpha) {
dst->alpha = malloc(dw * dh);
}
sdata = GETOFFSET_PIXEL(src, 0, 0);
ddata = GETOFFSET_PIXEL(dst, 0, 0);
sw = src->width;
sh = src->height;
a1 = (float)sw / (float)dw;
a2 = (float)sh / (float)dh;
row = malloc(sizeof(int) * dw);
// 1おおきくして初期化しないと col[dw-1]とcol[dw]が同じになる
// 可能性がある。
col = calloc(dh +1, sizeof(int));
if (mirror & 1) {
/* 上下反転 added by tajiri@wizard */
for (yd = sh - a2, y = 0; y < dh; y++) {
col[y] = yd; yd -= a2;
}
} else {
for (yd = 0.0, y = 0; y < dh; y++) {
col[y] = yd; yd += a2;
}
}
if (mirror & 2) {
/* 左右反転 added by tajiri@wizard */
for (xd = sw - a1, x = 0; x < dw; x++) {
row[x] = xd; xd -= a1;
}
} else {
for (xd = 0.0, x = 0; x < dw; x++) {
row[x] = xd; xd += a1;
}
}
#define SCALEDCOPYAREA(type) { \
int x, y; \
type *sl, *dl; \
uint8_t *_sl, *_dl; \
for (y = 0; y < dh; y++) { \
sl = (type *)(sdata + *(y + col) * src->bytes_per_line);\
dl = (type *)(ddata + y * dst->bytes_per_line);\
for (x = 0; x < dw; x++) { \
*(dl + x) = *(sl + *(row + x)); \
} \
_dl = (uint8_t *)dl; \
while (y < dh - 1 && *(col + y) == *(col + y + 1)) { \
_sl = _dl; \
_dl += dst->bytes_per_line; \
memcpy(_dl, _sl, dw * sizeof(type)); \
y++; \
} \
}}
switch(dst->depth) {
case 8:
SCALEDCOPYAREA(uint8_t); break;
case 16:
SCALEDCOPYAREA(uint16_t); break;
case 24:
case 32:
SCALEDCOPYAREA(uint32_t); break;
default:
break;
}
if (src->alpha) {
int x, y;
uint8_t *sl, *dl;
uint8_t *_sl, *_dl;
sdata = GETOFFSET_ALPHA(src, 0, 0);
ddata = GETOFFSET_ALPHA(dst, 0, 0);
for (y = 0; y < dh; y++) {
sl = (uint8_t *)(sdata + *(y + col) * src->width);
dl = (uint8_t *)(ddata + y * dst->width);
for (x = 0; x < dw; x++) {
*(dl + x) = *(sl + *(row + x));
}
_dl = (uint8_t *)dl;
while (y < dh - 1 && *(col + y) == *(col + y + 1)) {
_sl = _dl;
_dl += dst->width;
memcpy(_dl, _sl, dw);
y++;
}
}
}
free(row);
free(col);
return dst;
}
+13 -14
View File
@@ -1,12 +1,11 @@
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <SDL.h>
#include "portab.h"
#include "sprite.h"
#include "sactcg.h"
#include "surface.h"
#include "ngraph.h"
#include "nt_msg.h"
sprite_t *nt_sp_new(int no, int cg1, int cg2, int cg3, int type) {
@@ -29,11 +28,11 @@ sprite_t *nt_sp_new(int no, int cg1, int cg2, int cg3, int type) {
sp->cur = sp->loc;
if (sp->curcg == NULL) {
sp->cursize.width = 0;
sp->cursize.height = 0;
sp->width = 0;
sp->height = 0;
} else {
sp->cursize.width = sp->curcg->sf->width;
sp->cursize.height = sp->curcg->sf->height;
sp->width = sp->curcg->sf->w;
sp->height = sp->curcg->sf->h;
}
sp->update = DEFAULT_UPDATE;
@@ -59,11 +58,11 @@ sprite_t *nt_sp_msg_new(int no, int x, int y, int width, int height) {
sp->loc.x = x;
sp->loc.y = y;
sp->cur = sp->loc;
sp->cursize.width = width;
sp->cursize.height = height;
sp->width = width;
sp->height = height;
sp->u.msg.dspcur.x = 0;
sp->u.msg.dspcur.y = 0;
sp->u.msg.canvas = sf_create_surface(width, height, sf0->depth);
sp->u.msg.canvas = SDL_CreateRGBSurfaceWithFormat(0, width, height, 32, SDL_PIXELFORMAT_ARGB8888);
sp->update = ntmsg_update;
return sp;
@@ -77,7 +76,7 @@ void nt_sp_free(sprite_t *sp) {
if (sp->cg3) nt_scg_deref(sp->cg3);
if (sp->type == SPRITE_MSG) {
sf_free(sp->u.msg.canvas);
SDL_FreeSurface(sp->u.msg.canvas);
}
free(sp);
@@ -108,11 +107,11 @@ void nt_sp_set_cg(sprite_t *sp, int no) {
cg = no ? nt_scg_addref(no) : NULL;
if (cg == NULL) {
sp->cursize.width = 0;
sp->cursize.height = 0;
sp->width = 0;
sp->height = 0;
} else {
sp->cursize.width = cg->sf->width;
sp->cursize.height = cg->sf->height;
sp->width = cg->sf->w;
sp->height = cg->sf->h;
}
sp->curcg = cg;
+12 -14
View File
@@ -3,8 +3,7 @@
#define __SPRITE_H__
#include "portab.h"
#include "surface.h"
#include "graphics.h"
#include <SDL_rect.h>
#define DEFAULT_UPDATE nt_sp_draw
@@ -54,7 +53,7 @@ enum cgtype {
struct _cginfo {
enum cgtype type; // CGの種類, 0: 未使用, 1:リンクされている, ...
int no; // CGの番号
surface_t *sf; // CG本体
struct SDL_Surface *sf;
int refcnt; // 参照カウンタ。0になったら開放してもよい。
};
typedef struct _cginfo cginfo_t;
@@ -73,7 +72,8 @@ struct _sprite {
int no;
MyDimension cursize;
int width;
int height;
cginfo_t *curcg;
cginfo_t *cg1, *cg2, *cg3;
@@ -82,11 +82,11 @@ struct _sprite {
int blendrate;
MyPoint loc;
SDL_Point loc;
MyPoint cur;
SDL_Point cur;
void (* update)(struct _sprite *sp, MyRectangle *updatearea);
void (* update)(struct _sprite *sp, SDL_Rect *updatearea);
union {
struct {
@@ -97,8 +97,8 @@ struct _sprite {
} anime;
struct {
surface_t *canvas;
MyPoint dspcur;
struct SDL_Surface *canvas;
SDL_Point dspcur;
} msg;
} u;
};
@@ -121,14 +121,12 @@ void nt_sp_updateme(sprite_t *sp);
void nt_sp_updateme_part(sprite_t *sp, int x, int y, int w, int h);
void nt_sp_add_updatelist(sprite_t *sp);
void nt_sp_remove_updatelist(sprite_t *sp);
void nt_sp_draw_wall(sprite_t *sp, MyRectangle *r);
void nt_sp_draw_wall(sprite_t *sp, SDL_Rect *r);
void nt_sp_clear_updatelist(void);
/* in nt_sprite_draw.c */
void nt_sp_draw(sprite_t *sp, MyRectangle *r);
void nt_sp_draw2(sprite_t *sp, cginfo_t *cg, MyRectangle *r);
void nt_sp_draw_dmap(void* data, void* userdata);
void nt_sp_draw_scg(sprite_t *sp, MyRectangle *r);
void nt_sp_draw(sprite_t *sp, SDL_Rect *r);
void nt_sp_draw_scg(sprite_t *sp, SDL_Rect *r);
/* in nt_sprite_eupdate.c */
void nt_sp_eupdate(int type, int time, int cancel);
+29 -68
View File
@@ -24,14 +24,11 @@
#include "config.h"
#include <stdio.h>
#include <SDL.h>
#include "portab.h"
#include "system.h"
#include "ags.h"
#include "graphics.h"
#include "surface.h"
#include "graph.h"
#include "ngraph.h"
#include "sprite.h"
/*
@@ -39,95 +36,59 @@
@param sp: 描画するスプライト
@param r : 再描画する領域
*/
void nt_sp_draw(sprite_t *sp, MyRectangle *r) {
void nt_sp_draw(sprite_t *sp, SDL_Rect *r) {
if (sp == NULL) return;
nt_sp_draw2(sp, sp->curcg, r);
}
/*
指定の spriteの指定のCGを surface0 に書く
(このインターフェイスはもう不要?)
@param sp: 描画するスプライト
@param cg: 描画するCG
@param r : 再描画する領域
*/
void nt_sp_draw2(sprite_t *sp, cginfo_t *cg, MyRectangle *r) {
surface_t update;
int sx, sy, w, h, dx, dy;
cginfo_t *cg = sp->curcg;
if (cg == NULL) return;
if (cg->sf == NULL) return;
// 更新領域の確定
update.width = r->w;
update.height = r->h;
sx = 0;
sy = 0;
dx = sp->cur.x - r->x;
dy = sp->cur.y - r->y;
w = cg->sf->width;
h = cg->sf->height;
SDL_Rect cg_rect = {0, 0, cg->sf->w, cg->sf->h};
int sx = 0;
int sy = 0;
int dx = sp->cur.x;
int dy = sp->cur.y;
int w = cg->sf->w;
int h = cg->sf->h;
if (!gr_clip(cg->sf, &sx, &sy, &w, &h, &update, &dx, &dy)) {
if (!ags_clipCopyRect(&cg_rect, r, &sx, &sy, &dx, &dy, &w, &h)) {
return;
}
dx += r->x;
dy += r->y;
if (cg->sf->alpha) {
// alpha map がある場合
gre_BlendUseAMap(sf0, dx, dy,
sf0, dx, dy,
cg->sf, sx, sy, w, h,
cg->sf, sx, sy,
sp->blendrate);
if (SDL_ISPIXELFORMAT_ALPHA(cg->sf->format->format) || sp->blendrate < 255) {
SDL_SetSurfaceBlendMode(cg->sf, SDL_BLENDMODE_BLEND);
SDL_SetSurfaceAlphaMod(cg->sf, sp->blendrate);
} else {
if (sp->blendrate == 255) {
// alpha値指定が無い場合
gr_copy(sf0, dx, dy, cg->sf, sx, sy, w, h);
} else if (sp->blendrate > 0) {
// alpha値指定がある場合
gr_blend(sf0, dx, dy, cg->sf, sx, sy, w, h, sp->blendrate);
}
SDL_SetSurfaceBlendMode(cg->sf, SDL_BLENDMODE_NONE);
}
SDL_BlitSurface(cg->sf, &(SDL_Rect){sx, sy, w, h}, main_surface, &(SDL_Rect){dx, dy, w, h});
SACT_DEBUG("do update no=%d, sx=%d, sy=%d, w=%d, h=%d, dx=%d, dy=%d",
sp->no, sx, sy, w, h, dx, dy);
}
// BlendScreenによる描画
void nt_sp_draw_scg(sprite_t *sp, MyRectangle *r) {
surface_t update;
cginfo_t *cg;
int sx, sy, w, h, dx, dy;
void nt_sp_draw_scg(sprite_t *sp, SDL_Rect *r) {
if (sp == NULL) return;
cg = sp->curcg;
cginfo_t *cg = sp->curcg;
if (cg == NULL) return;
if (cg->sf == NULL) return;
// 更新領域の確定
update.width = r->w;
update.height = r->h;
sx = 0;
sy = 0;
dx = sp->cur.x - r->x;
dy = sp->cur.y - r->y;
w = cg->sf->width;
h = cg->sf->height;
SDL_Rect cg_rect = {0, 0, cg->sf->w, cg->sf->h};
int sx = 0;
int sy = 0;
int dx = sp->cur.x;
int dy = sp->cur.y;
int w = cg->sf->w;
int h = cg->sf->h;
if (!gr_clip(cg->sf, &sx, &sy, &w, &h, &update, &dx, &dy)) {
if (!ags_clipCopyRect(&cg_rect, r, &sx, &sy, &dx, &dy, &w, &h)) {
return;
}
dx += r->x;
dy += r->y;
gr_blend_screen(sf0, dx, dy, cg->sf, sx, sy, w, h);
SDL_SetSurfaceBlendMode(cg->sf, SDL_BLENDMODE_ADD);
SDL_BlitSurface(cg->sf, &(SDL_Rect){sx, sy, w, h}, main_surface, &(SDL_Rect){dx, dy, w, h});
SACT_DEBUG("do update no=%d, sx=%d, sy=%d, w=%d, h=%d, dx=%d, dy=%d",
sp->no, sx, sy, w, h, dx, dy);
+10 -10
View File
@@ -25,11 +25,11 @@
#include "portab.h"
#include "system.h"
#include "ngraph.h"
#include "ags.h"
#include "input.h"
#include "sprite.h"
#include "sdl_core.h"
#include "gfx.h"
#include "effect.h"
/*
効果つき画面更新
@@ -45,25 +45,25 @@ void nt_sp_eupdate(int no, int time, int cancel) {
nt_sp_update_all(false);
enum sdl_effect_type type = from_sact_effect(no - 100);
enum effect_type type = from_sact_effect(no - 100);
if (type == EFFECT_INVALID) {
WARNING("Unimplemented effect %d", no);
type = EFFECT_CROSSFADE;
}
SDL_Rect rect = { 0, 0, sf0->width, sf0->height };
struct sdl_effect *eff = sdl_effect_init(&rect, NULL, 0, 0, sdl_getDIB(), 0, 0, type);
SDL_Rect rect = { 0, 0, main_surface->w, main_surface->h };
struct effect *eff = effect_init(&rect, NULL, 0, 0, gfx_getDIB(), 0, 0, type);
int sttime, curtime;
sttime = curtime = sdl_getTicks();
sttime = curtime = sys_get_ticks();
int edtime = curtime + time;
while ((curtime = sdl_getTicks()) < edtime) {
sdl_effect_step(eff, (float)(curtime - sttime) / (edtime - sttime));
int rest = 16 - (sdl_getTicks() - curtime);
while ((curtime = sys_get_ticks()) < edtime) {
effect_step(eff, (float)(curtime - sttime) / (edtime - sttime));
int rest = 16 - (sys_get_ticks() - curtime);
int key = sys_keywait(rest, cancel ? KEYWAIT_CANCELABLE : KEYWAIT_NONCANCELABLE);
if (cancel && key)
break;
}
sdl_effect_finish(eff);
effect_finish(eff);
ags_updateFull();
}
+21 -34
View File
@@ -25,15 +25,12 @@
#include <stdio.h>
#include <stdlib.h>
#include <SDL.h>
#include "portab.h"
#include "system.h"
#include "list.h"
#include "ags.h"
#include "graphics.h"
// #include "sact.h"
#include "surface.h"
#include "ngraph.h"
#include "sprite.h"
// スプライト再描画間の間に変更のあったスプライトの領域の和
@@ -43,22 +40,22 @@ static SList *updatearea;
static SList *updatelist;
static void disjunction(void* region, void* data);
static MyRectangle get_updatearea();
static SDL_Rect get_updatearea();
static void do_update_each(void* data, void* userdata);
// 領域1と領域2をすべて含む矩形領域を計算
static void disjunction(void* region, void* data) {
MyRectangle *r1 = (MyRectangle *)region;
MyRectangle *r2 = (MyRectangle *)data;
SDL_Rect *r1 = (SDL_Rect *)region;
SDL_Rect *r2 = (SDL_Rect *)data;
SDL_UnionRect(r1, r2, r2);
free(r1);
}
// 更新の必要なスプライトの領域の和をとってクリッピングする
static MyRectangle get_updatearea() {
MyRectangle clip = {0, 0, 0, 0};
MyRectangle rsf0 = {0, 0, sf0->width, sf0->height};
MyRectangle result;
static SDL_Rect get_updatearea() {
SDL_Rect clip = {0, 0, 0, 0};
SDL_Rect screen = {0, 0, main_surface->w, main_surface->h};
SDL_Rect result;
slist_foreach(updatearea, disjunction, &clip);
@@ -66,7 +63,7 @@ static MyRectangle get_updatearea() {
updatearea = NULL;
// surface0との領域の積をとる
SDL_IntersectRect(&rsf0, &clip, &result);
SDL_IntersectRect(&screen, &clip, &result);
SACT_DEBUG("clipped area x=%d y=%d w=%d h=%d",
result.x, result.y, result.w, result.h);
@@ -77,7 +74,7 @@ static MyRectangle get_updatearea() {
// updatelist に登録してあるすべてのスプライトを更新
static void do_update_each(void* data, void* userdata) {
sprite_t *sp = (sprite_t *)data;
MyRectangle *r = (MyRectangle *)userdata;
SDL_Rect *r = (SDL_Rect *)userdata;
// 非表示の場合はなにもしない
if (!sp->show) return;
@@ -94,7 +91,7 @@ static void do_update_each(void* data, void* userdata) {
*/
void nt_sp_update_all(bool syncscreen) {
// 画面全体を更新領域に
MyRectangle r = {0, 0, sf0->width, sf0->height };
SDL_Rect r = {0, 0, main_surface->w, main_surface->h };
// updatelistに登録してあるスプライトを再描画
// updatelistはスプライトの番号順に並んでいる
@@ -113,7 +110,7 @@ void nt_sp_update_all(bool syncscreen) {
updateme(_part)で登録した更新が必要なspriteの和の領域をupdate
*/
void nt_sp_update_clipped() {
MyRectangle r;
SDL_Rect r;
// 更新領域の確定
r = get_updatearea();
@@ -133,16 +130,16 @@ void nt_sp_update_clipped() {
@param sp: 更新するスプライト
*/
void nt_sp_updateme(sprite_t *sp) {
MyRectangle *r;
SDL_Rect *r;
if (sp == NULL) return;
if (sp->cursize.width == 0 || sp->cursize.height == 0) return;
if (sp->width == 0 || sp->height == 0) return;
r = malloc(sizeof(MyRectangle));
r = malloc(sizeof(SDL_Rect));
r->x = sp->cur.x;
r->y = sp->cur.y;
r->w = sp->cursize.width;
r->h = sp->cursize.height;
r->w = sp->width;
r->h = sp->height;
updatearea = slist_append(updatearea, r);
@@ -159,12 +156,12 @@ void nt_sp_updateme(sprite_t *sp) {
@param h: 更新領域高さ
*/
void nt_sp_updateme_part(sprite_t *sp, int x, int y, int w, int h) {
MyRectangle *r;
SDL_Rect *r;
if (sp == NULL) return;
if (w == 0 || h == 0) return;
r = malloc(sizeof(MyRectangle));
r = malloc(sizeof(SDL_Rect));
r->x = sp->cur.x + x;
r->y = sp->cur.y + y;
r->w = w;
@@ -206,16 +203,6 @@ void nt_sp_clear_updatelist(void) {
}
// デフォルトの壁紙update
void nt_sp_draw_wall(sprite_t *sp, MyRectangle *area) {
int sx, sy, w, h;
sx = area->x;
sy = area->y;
w = area->w;
h = area->h;
gr_fill(sf0, sx, sy, w, h, 0, 0, 0);
SACT_DEBUG("do update no=%d, sx=%d, sy=%d, w=%d, h=%d",
sp->no, sx, sy, w, h);
void nt_sp_draw_wall(sprite_t *sp, SDL_Rect *area) {
SDL_FillRect(main_surface, area, SDL_MapRGB(main_surface->format, 0, 0, 0));
}
+8 -7
View File
@@ -32,9 +32,8 @@
#include "nact.h"
#include "alk.h"
#include "music.h"
#include "sdl_core.h"
#include "gfx.h"
#include "input.h"
#include "ngraph.h"
#include "cg.h"
#include "jpeg.h"
@@ -53,27 +52,29 @@ static void ndd_run(int demonum) {
if (mus)
musbgm_play(mus, 0, 100, 0);
uint32_t start = sdl_getTicks();
uint32_t start = sys_get_ticks();
while (!nact->is_quit) {
int i = (sdl_getTicks() - start) / (1000 / FPS);
int i = (sys_get_ticks() - start) / (1000 / FPS);
if (i >= alk->datanum)
break;
cgdata *cg = jpeg_extract(alk->entries[i].data, alk->entries[i].size);
if (cg) {
gr_drawimage24(sf0, cg, 0, 0);
SDL_Surface *sf = SDL_CreateRGBSurfaceWithFormatFrom(cg->pic, cg->width, cg->height, 24, cg->width * 3, SDL_PIXELFORMAT_RGB24);
SDL_BlitSurface(sf, NULL, main_surface, NULL);
ags_updateFull();
SDL_FreeSurface(sf);
cgdata_free(cg);
} else {
WARNING("Cannot decode CG %d in %s", i, alk_path);
}
int wait_ms = (i + 1) * (1000 / FPS) - (sdl_getTicks() - start);
int wait_ms = (i + 1) * (1000 / FPS) - (sys_get_ticks() - start);
if (wait_ms > 0) {
if (sys_keywait(wait_ms, KEYWAIT_CANCELABLE))
break;
} else {
sdl_updateScreen();
gfx_updateScreen();
if (sys_getInputInfo())
break;
}
+10 -11
View File
@@ -25,6 +25,7 @@
#include <stdio.h>
#include <string.h>
#include <SDL.h>
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
@@ -46,8 +47,6 @@
#include "sactsound.h"
#include "sactcrypto.h"
#include "sactchart.h"
#include "ngraph.h"
#include "surface.h"
#include "sactamask.h"
/*
@@ -147,7 +146,7 @@ static void Init() {
}
// create depth map
sact.dmap = sf_create_pixel(sf0->width, sf0->height, 16);
sact.dmap = SDL_CreateRGBSurface(0, main_surface->w, main_surface->h, 16, 0, 0, 0, 0);
// その他 System35 のデフォルト動作の変更
ags_setAntialiasedStringMode(true);
@@ -1614,10 +1613,10 @@ static void TimerWait() {
int wTimerID = getCaliValue();
int wCount = getCaliValue();
while (wCount > stimer_get(wTimerID) && !nact->is_quit) {
sys_keywait(10, KEYWAIT_NONCANCELABLE);
}
int msec = (wCount - stimer_get(wTimerID)) * 10;
if (msec > 0)
sys_keywait(msec, KEYWAIT_CTRL_CANCELABLE);
TRACE("SACT.TimerWait %d,%d:", wTimerID, wCount);
}
@@ -1628,9 +1627,9 @@ static void TimerWait() {
*/
static void Wait() {
int wCount = getCaliValue();
sys_keywait(wCount*10, KEYWAIT_NONCANCELABLE);
sys_keywait(wCount * 10, KEYWAIT_CTRL_CANCELABLE);
TRACE("SACT.Wait %d:", wCount);
}
@@ -2146,7 +2145,7 @@ static void SACT_reset(void) {
sp_reset();
scg_freeall();
sf_free(sact.dmap);
SDL_FreeSurface(sact.dmap);
memset(&sact, 0, sizeof(sact));
}
+17 -20
View File
@@ -25,11 +25,10 @@
#define __SACT_H__
#include "config.h"
#include <SDL_rect.h>
#include "portab.h"
#include "list.h"
#include "graphics.h"
#include "surface.h"
#include "ags.h"
#include "sacttimer.h"
#include "variable.h"
@@ -73,7 +72,7 @@ enum cgtype {
struct _cginfo {
enum cgtype type; // CGの種類, 0: 未使用, 1:リンクされている, ...
int no; // CGの番号
surface_t *sf; // CG本体
struct SDL_Surface *sf;
int refcnt; // 参照カウンタ。0になったら開放してもよい。
};
typedef struct _cginfo cginfo_t;
@@ -107,7 +106,8 @@ struct _sprite {
int numsound1, numsound2, numsound3;
// 初期 sprite の大きさ(cg1の大きさ)
MyDimension cursize;
int width;
int height;
// それぞれの状態で表示する CG
cginfo_t *cg1, *cg2, *cg3;
@@ -126,10 +126,10 @@ struct _sprite {
int freezed_state;
// 表示位置 (SetPos)
MyPoint loc;
SDL_Point loc;
// 現在のスプライトの表示位置
MyPoint cur;
SDL_Point cur;
// event callback
int (* eventcb)(struct _sprite *sp, agsevent_t *e); // for key/mouse
@@ -146,7 +146,7 @@ struct _sprite {
// move command 用パラメータ
struct {
MyPoint to; // 移動先
SDL_Point to; // 移動先
int time; // 移動完了時間
int speed; // 移動速度
int starttime; // 移動開始時刻
@@ -157,7 +157,7 @@ struct _sprite {
// SACT.Numeral用パラメータ
struct {
int cg[10];
MyPoint pos;
SDL_Point pos;
int span;
} numeral;
@@ -171,7 +171,7 @@ struct _sprite {
// ゲットスプライト
struct {
bool dragging; // ドラッグ中
MyPoint dragstart; // ドラッグ開始位置
SDL_Point dragstart; // ドラッグ開始位置
} get;
// プットスプライト
@@ -190,8 +190,8 @@ struct _sprite {
// メッセージスプライト
struct {
SList *buf; // 表示する文字のリスト
surface_t *canvas; // 文字を描画するsurface
MyPoint dspcur; // 現在の表示位置
struct SDL_Surface *canvas;
SDL_Point dspcur; // 現在の表示位置
} msg;
} u;
};
@@ -213,7 +213,7 @@ struct _sact {
cginfo_t *cg[CGMAX]; // cgまたはCG_xxで作った CG
// 座標系の原点
MyPoint origin;
SDL_Point origin;
// 文字列 replce 用
SList *strreplace;
@@ -234,7 +234,7 @@ struct _sact {
int align; // 行そろえ
void (* cbmove)(agsevent_t *);
void (* cbrelease)(agsevent_t *);
surface_t *charcanvas;
struct SDL_Surface *charcanvas;
} sel;
// event listener
@@ -247,10 +247,7 @@ struct _sact {
int movestarttime; // 一斉に移動を開始するための開始時間
int movecurtime;
MyRectangle updaterect; // 更新が必要なspriteの領域の和
// sact timer
stimer_t timer[65536];
SDL_Rect updaterect; // 更新が必要なspriteの領域の和
// DnDに関するもの
sprite_t *draggedsp; // drag中のスプライト
@@ -273,7 +270,7 @@ struct _sact {
int numsoundob;
// depth map
surface_t *dmap;
struct SDL_Surface *dmap;
bool zhiding; // Zkeyによる隠し中
int zofftime;
@@ -281,7 +278,7 @@ struct _sact {
// バックログ
bool logging;
List *log;
List *log; // UTF-8 strings
};
typedef struct _sact sact_t;
+15 -75
View File
@@ -25,23 +25,18 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <SDL.h>
#include "portab.h"
#include "system.h"
#include "LittleEndian.h"
#include "input.h"
#include "ags.h"
#include "sact.h"
#include "surface.h"
#include "ngraph.h"
#include "pms.h"
#include "sprite.h"
#include "sdl_core.h"
#include "effect.h"
#include "mmap.h"
static surface_t *smask_get(int no);
static surface_t *smask_mul(surface_t *sf, int val);
// SACTEFAM を使ったマスク
typedef struct {
mmap_t *mmap;
@@ -52,16 +47,6 @@ typedef struct {
static SACTEFAM_t am;
struct ecopyparam {
int sttime;
int curtime;
int edtime;
int curstep;
int oldstep;
};
typedef struct ecopyparam ecopyparam_t;
static ecopyparam_t ecp;
// SACTEFAM.KLD の読み込み
bool smask_init(char *path) {
if (am.mmap)
@@ -84,7 +69,7 @@ bool smask_init(char *path) {
}
// 指定番号の alphamask ファイルをよみだす
static surface_t *smask_get(int no) {
static cgdata *smask_get(int no) {
int i;
for (i = 0; i < am.datanum; i++) {
@@ -93,70 +78,25 @@ static surface_t *smask_get(int no) {
if (i == am.datanum) return NULL;
return sf_getcg(am.mmap->addr + am.offset[i], 0 /*FIXME*/);
}
// ベースになるマスクの alpha 値を拡大して取り出す
static surface_t *smask_mul(surface_t *sf, int val) {
surface_t *out = sf_create_alpha(sf->width, sf->height);
uint8_t *src = sf->alpha;
uint8_t *dst = out->alpha;
int pix = sf->width * sf->height;
while(pix--) {
int i = (*src - val) * 16;
if (i < 0) *dst = 255; // 指定値よりも大きいのはコピー
else if (i > 255) *dst = 0; // 指定値よりも小さいのは無視
else *dst = 255-i; // それ以外は値を16倍
src++; dst++;
}
return out;
return pms256_extract(am.mmap->addr + am.offset[i]);
}
/**
* マスクつき画面更新
*/
void sp_eupdate_amap(int index, int time, int cancel) {
surface_t *mask, *mask2;
surface_t *sfsrc, *sfdst;
int key;
mask = smask_get(index);
cgdata *mask = smask_get(index);
if (mask == NULL) {
sp_update_all(true);
return;
}
// 現在の sf0 をセーブ
sfsrc = sf_dup(sf0);
sp_update_all(false);
sfdst = sf_dup(sf0);
sf_copyall(sf0, sfsrc);
ecp.sttime = ecp.curtime = sdl_getTicks();
ecp.edtime = ecp.curtime + time*10;
ecp.oldstep = 0;
while ((ecp.curtime = sdl_getTicks()) < ecp.edtime) {
int curstep = 255 * (ecp.curtime - ecp.sttime)/ (ecp.edtime - ecp.sttime);
// 元になるマスクのalpha値を16倍して欲しいところだけ取り出す
mask2 = smask_mul(mask, curstep);
gre_BlendUseAMap(sf0, 0, 0, sfsrc, 0, 0, sfdst, 0, 0, sfsrc->width, sfsrc->height, mask2, 0, 0, 255);
ags_updateFull();
key = sys_keywait(10, cancel ? KEYWAIT_CANCELABLE : KEYWAIT_NONCANCELABLE);
if (cancel && key) break;
// 一時マスクを削除
sf_free(mask2);
}
sf_copyall(sf0, sfdst);
SDL_Surface *mask_sf = SDL_CreateRGBSurfaceFrom(mask->pic, mask->width, mask->height, 8, mask->width, 0, 0, 0, 0);
sp_update_all(false); // old = gfx_texture, new = main_surface
struct effect *eff = effect_sactamask_init(mask_sf);
ags_runEffect(time * 10, cancel, (ags_EffectStepFunc)effect_step, eff);
effect_finish(eff);
ags_updateFull();
sf_free(sfsrc);
sf_free(sfdst);
sf_free(mask);
SDL_FreeSurface(mask_sf);
cgdata_free(mask);
}
+1
View File
@@ -25,5 +25,6 @@
#define __SACTAMASK_H__
bool smask_init(const char *path);
void sp_eupdate_amap(int type, int time, int key);
#endif
+90 -50
View File
@@ -23,9 +23,11 @@
#include "config.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <SDL.h>
#include "portab.h"
#include "nact.h"
@@ -33,11 +35,8 @@
#include "ags.h"
#include "sact.h"
#include "sactcg.h"
#include "surface.h"
#include "ngraph.h"
#include "sactcg_stretch.c"
#include "sactcg_blend.c"
#include "cg.h"
#include "gfx.h"
#define SPCG_ASSERT_NO(no) \
if ((no) > (CGMAX -1)) { \
@@ -45,7 +44,7 @@
return; \
} \
static cginfo_t *scg_new(enum cgtype type, int no, surface_t *sf) {
static cginfo_t *scg_new(enum cgtype type, int no, SDL_Surface *sf) {
cginfo_t *info = calloc(1, sizeof(cginfo_t));
info->type = type;
info->no = no;
@@ -75,7 +74,7 @@ static cginfo_t *scg_get(int no) {
if (sact.cg[no] != NULL)
return sact.cg[no];
surface_t *sf = sf_loadcg_no(no - 1);
SDL_Surface *sf = cg_load_as_sdlsurface(no - 1);
if (!sf) {
WARNING("load fail (%d)", no -1);
return NULL;
@@ -95,7 +94,7 @@ void scg_deref(cginfo_t *cg) {
return;
if (cg->sf)
sf_free(cg->sf);
SDL_FreeSurface(cg->sf);
free(cg);
}
@@ -103,9 +102,8 @@ void scg_deref(cginfo_t *cg) {
void scg_create(int wNumCG, int wWidth, int wHeight, int wR, int wG, int wB, int wBlendRate) {
SPCG_ASSERT_NO(wNumCG);
surface_t *sf = sf_create_surface(wWidth, wHeight, sf0->depth);
gr_fill(sf, 0, 0, wWidth, wHeight, wR, wG, wB);
gr_fill_alpha_map(sf, 0, 0, wWidth, wHeight, wBlendRate);
SDL_Surface *sf = SDL_CreateRGBSurfaceWithFormat(0, wWidth, wHeight, 32, SDL_PIXELFORMAT_ARGB8888);
SDL_FillRect(sf, NULL, SDL_MapRGBA(sf->format, wR, wG, wB, wBlendRate));
scg_new(CG_SET, wNumCG, sf);
}
@@ -118,7 +116,11 @@ void scg_create_reverse(int wNumCG, int wNumSrcCG, int wReverseX, int wReverseY)
if (!src)
return;
surface_t *sf = stretch(src->sf, src->sf->width, src->sf->height, (wReverseX << 1) | wReverseY);
SDL_Surface *sf = SDL_ConvertSurface(src->sf, src->sf->format, 0);
if (wReverseX)
gfx_FlipSurfaceHorizontal(sf);
if (wReverseY)
gfx_FlipSurfaceVertical(sf);
scg_new(CG_REVERSE, wNumCG, sf);
}
@@ -130,11 +132,64 @@ void scg_create_stretch(int wNumCG, int wWidth, int wHeight, int wNumSrcCG) {
cginfo_t *src = scg_get(wNumSrcCG);
if (!src)
return;
surface_t *sf = stretch(src->sf, wWidth, wHeight, 0);
SDL_Surface *sf = SDL_CreateRGBSurfaceWithFormat(0, wWidth, wHeight, src->sf->format->BitsPerPixel, src->sf->format->format);
SDL_BlitScaled(src->sf, NULL, sf, NULL);
scg_new(CG_STRETCH, wNumCG, sf);
}
static SDL_Surface *blend(SDL_Surface *base, int x, int y, SDL_Surface *blend, int mode) {
assert(blend->format->format == SDL_PIXELFORMAT_ARGB8888 || blend->format->format == SDL_PIXELFORMAT_XRGB8888);
bool src_has_alpha = SDL_ISPIXELFORMAT_ALPHA(blend->format->format);
SDL_Surface *dst = SDL_ConvertSurfaceFormat(base, SDL_PIXELFORMAT_ARGB8888, 0);
SDL_Rect rect = {x, y, blend->w, blend->h};
SDL_IntersectRect(&(SDL_Rect){0, 0, dst->w, dst->h}, &rect, &rect);
for (int i = 0; i < rect.h; i++) {
uint8_t *dstp = (uint8_t *)dst->pixels + (i + rect.y) * dst->pitch + rect.x * 4;
uint8_t *srcp = (uint8_t *)blend->pixels + i * blend->pitch;
for (int j = 0; j < rect.w; j++) {
uint8_t *dstpp = dstp + j * 4;
uint8_t *srcpp = srcp + j * 4;
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
// Use base's alpha map if blend has no alpha map
uint8_t alpha = src_has_alpha ? srcpp[3] : dstpp[3];
if (alpha == 0) {
// do nothing
} else if (alpha == 255) {
memcpy(dstpp, srcpp, 3);
} else {
for (int k = 0; k < 3; k++) {
dstpp[k] = (dstpp[k] * (255 - alpha) + srcpp[k] * alpha) / 255;
}
}
if (mode) {
int dsta = dstpp[3] + srcpp[3];
dstpp[3] = dsta > 255 ? 255 : dsta;
}
#else
// Use base's alpha map if blend has no alpha map
uint8_t alpha = src_has_alpha ? srcpp[0] : dstpp[0];
if (alpha == 0) {
// do nothing
} else if (alpha == 255) {
memcpy(dstpp + 1, srcpp + 1, 3);
} else {
for (int k = 1; k < 4; k++) {
dstpp[k] = (dstpp[k] * (255 - alpha) + srcpp[k] * alpha) / 255;
}
}
if (mode) {
int dsta = dstpp[0] + srcpp[0];
dstpp[0] = dsta > 255 ? 255 : dsta;
}
#endif
}
}
return dst;
}
// ベースCGの上にブレンドCGを重ねた CG を作成
void scg_create_blend(int wNumDstCG, int wNumBaseCG, int wX, int wY, int wNumBlendCG, int wAlphaMapMode) {
SPCG_ASSERT_NO(wNumDstCG);
@@ -145,7 +200,7 @@ void scg_create_blend(int wNumDstCG, int wNumBaseCG, int wX, int wY, int wNumBle
cginfo_t *blendcg = scg_get(wNumBlendCG);
if (!basecg || !blendcg) return;
surface_t *sf = blend(basecg->sf, wX, wY, blendcg->sf, wAlphaMapMode);
SDL_Surface *sf = blend(basecg->sf, wX, wY, blendcg->sf, wAlphaMapMode);
scg_new(CG_SET, wNumDstCG, sf);
}
@@ -157,11 +212,12 @@ void scg_create_text(int wNumCG, int wSize, int wR, int wG, int wB, int wText) {
if (svar_length(wText) == 0) return;
ags_setFont(FONT_GOTHIC, wSize);
agsurface_t *glyph = ags_drawStringToSurface(svar_get(wText));
SDL_Surface *glyph = ags_drawStringToSurface(svar_get(wText), wR, wG, wB);
surface_t *sf = sf_create_surface(glyph->width, wSize, nact->ags.dib->depth);
gr_fill(sf, 0, 0, glyph->width, wSize, wR, wG, wB);
gr_draw_amap(sf, 0, 0, glyph->pixel, glyph->width, wSize, glyph->bytes_per_line);
SDL_Surface *sf = SDL_CreateRGBSurfaceWithFormat(0, glyph->w, wSize, 32, SDL_PIXELFORMAT_ARGB8888);
SDL_SetSurfaceBlendMode(glyph, SDL_BLENDMODE_NONE);
SDL_BlitSurface(glyph, NULL, sf, NULL);
SDL_FreeSurface(glyph);
scg_new(CG_SET, wNumCG, sf);
}
@@ -181,11 +237,12 @@ void scg_create_textnum(int wNumCG, int wSize, int wR, int wG, int wB, int wFigs
sprintf(s, ss, wValue);
ags_setFont(FONT_GOTHIC, wSize);
agsurface_t *glyph = ags_drawStringToSurface(s);
SDL_Surface *glyph = ags_drawStringToSurface(s, wR, wG, wB);
surface_t *sf = sf_create_surface(glyph->width, wSize, nact->ags.dib->depth);
gr_fill(sf, 0, 0, glyph->width, wSize, wR, wG, wB);
gr_draw_amap(sf, 0, 0, glyph->pixel, glyph->width, wSize, glyph->bytes_per_line);
SDL_Surface *sf = SDL_CreateRGBSurfaceWithFormat(0, glyph->w, wSize, 32, SDL_PIXELFORMAT_ARGB8888);
SDL_SetSurfaceBlendMode(glyph, SDL_BLENDMODE_NONE);
SDL_BlitSurface(glyph, NULL, sf, NULL);
SDL_FreeSurface(glyph);
scg_new(CG_SET, wNumCG, sf);
}
@@ -199,7 +256,7 @@ void scg_copy(int wNumDstCG, int wNumSrcCG) {
if (!src)
return;
scg_new(CG_SET, wNumDstCG, sf_dup(src->sf));
scg_new(CG_SET, wNumDstCG, SDL_ConvertSurface(src->sf, src->sf->format, 0));
}
// CGの一部を切りぬいたCGを作成
@@ -211,14 +268,8 @@ void scg_cut(int wNumDstCG, int wNumSrcCG, int wX, int wY, int wWidth, int wHeig
if (!src)
return;
surface_t *sf = src->sf->alpha
? sf_create_surface(wWidth, wHeight, src->sf->depth)
: sf_create_pixel(wWidth, wHeight, src->sf->depth);
if (src->sf->pixel)
gr_copy(sf, 0, 0, src->sf, wX, wY, wWidth, wHeight);
if (src->sf->alpha)
gr_copy_alpha_map(sf, 0, 0, src->sf, wX, wY, wWidth, wHeight);
SDL_Surface *sf = SDL_CreateRGBSurfaceWithFormat(0, wWidth, wHeight, src->sf->format->BitsPerPixel, src->sf->format->format);
SDL_BlitSurface(src->sf, &(SDL_Rect){wX, wY, wWidth, wHeight}, sf, NULL);
scg_new(CG_SET, wNumDstCG, sf);
}
@@ -232,18 +283,9 @@ void scg_partcopy(int wNumDstCG, int wNumSrcCG, int wX, int wY, int wWidth, int
if (!src)
return;
surface_t *sf;
if (src->sf->alpha) {
sf = sf_create_surface(src->sf->width, src->sf->height, src->sf->depth);
gr_fill_alpha_map(sf, 0, 0, src->sf->width, src->sf->height, 255);
} else {
sf = sf_create_pixel(src->sf->width, src->sf->height, src->sf->depth);
}
if (src->sf->pixel)
gr_copy(sf, wX, wY, src->sf, wX, wY, wWidth, wHeight);
if (src->sf->alpha)
gr_copy_alpha_map(sf, wX, wY, src->sf, wX, wY, wWidth, wHeight);
SDL_Surface *sf = SDL_CreateRGBSurfaceWithFormat(0, src->sf->w, src->sf->h, src->sf->format->BitsPerPixel, src->sf->format->format);
SDL_FillRect(sf, NULL, SDL_MapRGBA(sf->format, 0, 0, 0, 255));
SDL_BlitSurface(src->sf, &(SDL_Rect){wX, wY, wWidth, wHeight}, sf, &(SDL_Rect){wX, wY, wWidth, wHeight});
scg_new(CG_SET, wNumDstCG, sf);
}
@@ -284,8 +326,8 @@ bool scg_querysize(int wNumCG, int *w, int *h) {
if (sact.cg[wNumCG] == NULL) goto errexit;
if (sact.cg[wNumCG]->sf == NULL) goto errexit;
*w = sact.cg[wNumCG]->sf->width;
*h = sact.cg[wNumCG]->sf->height;
*w = sact.cg[wNumCG]->sf->w;
*h = sact.cg[wNumCG]->sf->h;
return true;
@@ -299,8 +341,7 @@ int scg_querybpp(int wNumCG) {
if (wNumCG >= (CGMAX -1)) return 0;
if (sact.cg[wNumCG] == NULL) return 0;
if (sact.cg[wNumCG]->sf == NULL) return 0;
return sact.cg[wNumCG]->sf->depth;
return sact.cg[wNumCG]->sf->format->BitsPerPixel;
}
// CGの alphamap が存在するかを取得
@@ -308,6 +349,5 @@ bool scg_existalphamap(int wNumCG) {
if (wNumCG >= (CGMAX -1)) return false;
if (sact.cg[wNumCG] == NULL) return false;
if (sact.cg[wNumCG]->sf == NULL) return false;
return sact.cg[wNumCG]->sf->alpha;
return SDL_ISPIXELFORMAT_ALPHA(sact.cg[wNumCG]->sf->format->format);
}
-31
View File
@@ -1,31 +0,0 @@
//
static surface_t *blend(surface_t *base, int x, int y, surface_t *blend, int mode) {
surface_t *dst = sf_create_surface(base->width, base->height, base->depth);
gr_copy(dst, 0, 0, base, 0, 0, base->width, base->height);
if (base->alpha) {
// ベースに alpha map がある場合はそれをコピー
gr_copy_alpha_map(dst, 0, 0, base, 0, 0, base->width, base->height);
} else {
// 無い場合は全て 255 の map を作成
gr_fill_alpha_map(dst, 0, 0, base->width, base->height, 255);
}
if (blend->alpha) {
// 重ね合わせ先の alpha map があるときはそれを使う
gre_BlendUseAMap(dst, x, y, base, x, y, blend, 0, 0, blend->width, blend->height, blend, 0, 0, 255);
} else {
// 無いときは dst の alpha map を使う
gre_BlendUseAMap(dst, x, y, base, x, y, blend, 0, 0, blend->width, blend->height, dst, x, y, 255);
}
// alpha 作成モードが dst + blend の時は飽和加算
if (mode == 1) {
gr_saturadd_alpha_map(dst, x, y, blend, 0, 0, blend->width, blend->height);
}
return dst;
}
-114
View File
@@ -1,114 +0,0 @@
// 拡大縮小
static surface_t *stretch(surface_t *src, int dw, int dh, int mirror) {
surface_t *dst = calloc(1, sizeof(surface_t));
float a1, a2, xd, yd;
int sw, sh;
int *row, *col;
int x, y;
uint8_t *sdata, *ddata;
dst->width = dw;
dst->height = dh;
dst->depth = src->depth;
dst->bytes_per_line = dw * src->bytes_per_pixel;
dst->bytes_per_pixel = src->bytes_per_pixel;
if (src->pixel) {
dst->pixel = malloc(dh * dst->bytes_per_line);
}
if (src->alpha) {
dst->alpha = malloc(dw * dh);
}
sdata = GETOFFSET_PIXEL(src, 0, 0);
ddata = GETOFFSET_PIXEL(dst, 0, 0);
sw = src->width;
sh = src->height;
a1 = (float)sw / (float)dw;
a2 = (float)sh / (float)dh;
row = malloc(sizeof(int) * dw);
// 1おおきくして初期化しないと col[dw-1]とcol[dw]が同じになる
// 可能性がある。
col = calloc(dh +1, sizeof(int));
if (mirror & 1) {
/* 上下反転 added by tajiri@wizard */
for (yd = sh - a2, y = 0; y < dh; y++) {
col[y] = yd; yd -= a2;
}
} else {
for (yd = 0.0, y = 0; y < dh; y++) {
col[y] = yd; yd += a2;
}
}
if (mirror & 2) {
/* 左右反転 added by tajiri@wizard */
for (xd = sw - a1, x = 0; x < dw; x++) {
row[x] = xd; xd -= a1;
}
} else {
for (xd = 0.0, x = 0; x < dw; x++) {
row[x] = xd; xd += a1;
}
}
#define SCALEDCOPYAREA(type) { \
int x, y; \
type *sl, *dl; \
uint8_t *_sl, *_dl; \
for (y = 0; y < dh; y++) { \
sl = (type *)(sdata + *(y + col) * src->bytes_per_line);\
dl = (type *)(ddata + y * dst->bytes_per_line);\
for (x = 0; x < dw; x++) { \
*(dl + x) = *(sl + *(row + x)); \
} \
_dl = (uint8_t *)dl; \
while (y < dh - 1 && *(col + y) == *(col + y + 1)) { \
_sl = _dl; \
_dl += dst->bytes_per_line; \
memcpy(_dl, _sl, dw * sizeof(type)); \
y++; \
} \
}}
switch(dst->depth) {
case 8:
SCALEDCOPYAREA(uint8_t); break;
case 16:
SCALEDCOPYAREA(uint16_t); break;
case 24:
case 32:
SCALEDCOPYAREA(uint32_t); break;
default:
break;
}
if (src->alpha) {
int x, y;
uint8_t *sl, *dl;
uint8_t *_sl, *_dl;
sdata = GETOFFSET_ALPHA(src, 0, 0);
ddata = GETOFFSET_ALPHA(dst, 0, 0);
for (y = 0; y < dh; y++) {
sl = (uint8_t *)(sdata + *(y + col) * src->width);
dl = (uint8_t *)(ddata + y * dst->width);
for (x = 0; x < dw; x++) {
*(dl + x) = *(sl + *(row + x));
}
_dl = (uint8_t *)dl;
while (y < dh - 1 && *(col + y) == *(col + y + 1)) {
_sl = _dl;
_dl += dst->width;
memcpy(_dl, _sl, dw);
y++;
}
}
}
free(row);
free(col);
return dst;
}
+35 -37
View File
@@ -26,6 +26,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <SDL.h>
#include "portab.h"
#include "system.h"
@@ -35,13 +36,13 @@
#include "nact.h"
#include "sact.h"
#include "sprite.h"
#include "ngraph.h"
#include "drawtext.h"
#include "utfsjis.h"
#include "gfx.h"
#include "ags.h"
#include "font.h"
#define LOGMSG_LINES 6
static const char *logmsg_utf8[LOGMSG_LINES] = {
static char *logmsg[LOGMSG_LINES] = {
"\n",
"※バックログ操作方法※",
"[ESC]またはマウス右クリックでゲームに戻る",
@@ -56,12 +57,11 @@ static const char *logmsg_utf8[LOGMSG_LINES] = {
PageUP/Downで1ページ送り
*/
#define FONTSIZEINDEX 10
#define INDEX_FONTSIZE 10
#define FONTSIZE 20
#define LOGLINENUM (sf0->height / FONTSIZE)
#define LOGLINENUM (main_surface->h / FONTSIZE)
static int curline;
static surface_t *back;
static surface_t *chr;
static SDL_Surface *back;
static void draw_log() {
int i, y = 0, len;
@@ -69,14 +69,24 @@ static void draw_log() {
char pinfo[256];
List *node;
// canvas clear
memset(chr->pixel, 0, chr->bytes_per_line * chr->height);
#ifdef __EMSCRIPTEN__
load_mincho_font();
#endif
SDL_Surface *hline = SDL_CreateRGBSurfaceWithFormat(0, main_surface->w, 3, 32, SDL_PIXELFORMAT_RGB888);
SDL_FillRect(hline, NULL, SDL_MapRGB(hline->format, 255, 255, 255));
SDL_SetSurfaceBlendMode(hline, SDL_BLENDMODE_BLEND);
SDL_SetSurfaceAlphaMod(hline, 128);
SDL_SetSurfaceColorMod(back, 128, 128, 128);
SDL_BlitSurface(back, NULL, main_surface, NULL);
SDL_SetSurfaceColorMod(back, 255, 255, 255);
// ページ位置情報
len = snprintf(pinfo, sizeof(pinfo) -1, "%d/%d", curline, list_length(sact.log));
dt_setfont(FONT_GOTHIC, FONTSIZEINDEX);
dt_drawtext(chr, sf0->width - FONTSIZEINDEX *len /2, 0, pinfo);
ags_setFont(FONT_GOTHIC, INDEX_FONTSIZE);
gfx_drawString(main_surface->w - INDEX_FONTSIZE * len / 2, 0, pinfo, 255);
// 表示始め位置
node = list_nth(sact.log, list_length(sact.log) - curline);
@@ -85,23 +95,20 @@ static void draw_log() {
char *str = (char *)(node->data);
if (0 == strcmp(str, "\n")) {
gr_fill(chr, 0, y + FONTSIZE/2, sf0->width, 3, 128, 0, 0);
SDL_BlitSurface(hline, NULL, main_surface, &(SDL_Rect){0, y + FONTSIZE/2, main_surface->w, 3});
} else {
if (cur < 6) {
dt_setfont(FONT_MINCHO, FONTSIZE);
ags_setFont(FONT_MINCHO, FONTSIZE);
} else {
dt_setfont(FONT_GOTHIC, FONTSIZE);
ags_setFont(FONT_GOTHIC, FONTSIZE);
}
dt_drawtext(chr, 0, y, str);
gfx_drawString(0, y, str, 255);
}
y += FONTSIZE;
cur--;
node = list_next(node);
}
gr_copy_bright(sf0, 0, 0, back, 0, 0, sf0->width, sf0->height, 128);
gr_expandcolor_blend(sf0, 0, 0, chr, 0, 0, sf0->width, sf0->height,
255, 255, 255);
ags_updateFull();
}
@@ -111,18 +118,11 @@ bool sblog_start(void) {
if (sact.version < 120)
return false;
static char *logmsg[LOGMSG_LINES];
if (!logmsg[0]) {
for (int i = 0; i < LOGMSG_LINES; i++)
logmsg[i] = fromUTF8(logmsg_utf8[i]);
}
// 説明文章を追加
// Append instruction text
for (int i = 0; i < LOGMSG_LINES; i++)
sact.log = list_append(sact.log, logmsg[i]);
back = sf_dup(sf0);
chr = sf_create_surface(sf0->width, sf0->height, 8);
back = SDL_ConvertSurface(main_surface, main_surface->format, 0);
curline = 6;
draw_log();
return true;
@@ -132,16 +132,14 @@ void sblog_end(void) {
List *node;
int i;
sf_copyall(sf0, back);
SDL_BlitSurface(back, NULL, main_surface, NULL);
ags_updateFull();
sf_free(back);
sf_free(chr);
// 説明文章を削除
SDL_FreeSurface(back);
// Remove instruction text
for (i = 0; i < LOGMSG_LINES; i++) {
node = list_last(sact.log);
sact.log = list_remove(sact.log, node->data);
sact.log = list_remove(sact.log, logmsg[i]);
}
}
+20 -21
View File
@@ -22,36 +22,35 @@
/* $Id: sacttimer.c,v 1.1 2003/04/22 16:29:52 chikama Exp $ */
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
#include <string.h>
#include "portab.h"
#include "sact.h"
#include "sacttimer.h"
#include "system.h"
#define MAX_TIMER 10
#define TICKS_PER_CENTISECOND 10
uint32_t ticks_base[MAX_TIMER];
/*
sact timer subsystem 初期化
*/
void stimer_init(void) {
stimer_reset(0, 0);
memset(ticks_base, 0, sizeof(ticks_base));
}
// 指定IDのタイマーのリセット
void stimer_reset(int id, int val) {
gettimeofday(&(sact.timer[id].tv_base), NULL);
sact.timer[id].val = val;
if (id < 0 || id >= MAX_TIMER) {
WARNING("Invalid timer ID: %d", id);
return;
}
ticks_base[id] = sys_get_ticks() - (val * TICKS_PER_CENTISECOND);
}
// 指定IDのタイマーの取得
int stimer_get(int id) {
long sec, usec, usec2;
struct timeval tv;
struct timeval tv_base = sact.timer[id].tv_base;
int division = 10;
gettimeofday(&tv, NULL);
sec = tv.tv_sec - tv_base.tv_sec;
usec = tv.tv_usec - tv_base.tv_usec;
usec2 = sec * (1000l/division)+ usec / 1000l /division;
return sact.timer[id].val + usec2;
if (id < 0 || id >= MAX_TIMER) {
WARNING("Invalid timer ID: %d", id);
return 0;
}
uint32_t ticks = sys_get_ticks();
uint32_t diff = ticks - ticks_base[id];
return diff / TICKS_PER_CENTISECOND;
}
-10
View File
@@ -24,16 +24,6 @@
#ifndef __SACTTIMER_H__
#define __SACTTIMER_H__
#include <sys/time.h>
#include <unistd.h>
struct _stimer {
int val;
struct timeval tv_base;
};
typedef struct _stimer stimer_t;
void stimer_init(void);
void stimer_reset(int id, int val);
int stimer_get(int id);
+4 -7
View File
@@ -33,10 +33,7 @@
#include "ags.h"
#include "input.h"
#include "sact.h"
#include "surface.h"
#include "ngraph.h"
#include "sprite.h"
#include "sdl_core.h"
#include "randMT.h"
#define M_PIf ((float)M_PI)
@@ -80,20 +77,20 @@ void sp_quake_screen(int type, int p1, int p2, int time, int cancel) {
if (type > 1) return;
sttime = sdl_getTicks();
sttime = sys_get_ticks();
edtime = time * 10 + sttime;
while ((curtime = sdl_getTicks()) < edtime) {
while ((curtime = sys_get_ticks()) < edtime) {
int adjx, adjy;
cb[type]((float)(curtime - sttime)/(edtime - sttime), p1, p2, &adjx, &adjy);
ags_setViewArea(adjx, adjy, sf0->width, sf0->height);
ags_setViewArea(adjx, adjy, main_surface->w, main_surface->h);
ags_updateFull();
key = sys_keywait(10, cancel ? KEYWAIT_CANCELABLE : KEYWAIT_NONCANCELABLE);
if (cancel && key) break;
}
ags_setViewArea(0, 0, sf0->width, sf0->height);
ags_setViewArea(0, 0, main_surface->w, main_surface->h);
ags_updateFull();
}
+20 -30
View File
@@ -26,16 +26,15 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <SDL.h>
#include "portab.h"
#include "system.h"
#include "list.h"
#include "ngraph.h"
#include "ags.h"
#include "nact.h"
#include "sact.h"
#include "sprite.h"
#include "surface.h"
#include "sactcg.h"
#include "sactsound.h"
@@ -66,16 +65,7 @@ static int compare_spriteno_smallfirst(const void *a, const void *b) {
// デフォルトの壁紙update
static void sp_draw_wall(sprite_t *sp) {
int sx, sy, w, h;
sx = sact.updaterect.x;
sy = sact.updaterect.y;
w = sact.updaterect.w;
h = sact.updaterect.h;
gr_fill(sf0, sx, sy, w, h, 0, 0, 0);
SACT_DEBUG("do update no=%d, sx=%d, sy=%d, w=%d, h=%d",
sp->no, sx, sy, w, h);
SDL_FillRect(main_surface, &sact.updaterect, SDL_MapRGB(main_surface->format, 0, 0, 0));
}
/**
@@ -155,11 +145,11 @@ void sp_new(int no, int cg1, int cg2, int cg3, int type) {
// cg1の大きさをスプライトの大きさとする
if (sp->curcg == NULL) {
sp->cursize.width = 0;
sp->cursize.height = 0;
sp->width = 0;
sp->height = 0;
} else {
sp->cursize.width = sp->curcg->sf->width;
sp->cursize.height = sp->curcg->sf->height;
sp->width = sp->curcg->sf->w;
sp->height = sp->curcg->sf->h;
}
sp->freezed_state = 0; // 状態固定は無し
@@ -211,14 +201,14 @@ void sp_new_msg(int no, int x, int y, int width, int height) {
sp->loc.y = y - sact.origin.y;
sp->u.msg.dspcur.x = 0; // 文字描画開始位置
sp->u.msg.dspcur.y = 0;
sp->cursize.width = width; // スプライトの大きさ
sp->cursize.height = height;
sp->width = width; // スプライトの大きさ
sp->height = height;
sp->cur = sp->loc;
sp->u.msg.buf = NULL;
// 文字描画用キャンバス
sp->u.msg.canvas = sf_create_surface(width, height, sf0->depth);
// canvas for drawing text
sp->u.msg.canvas = SDL_CreateRGBSurfaceWithFormat(0, width, height, 32, SDL_PIXELFORMAT_ARGB8888);
// スプライト再描画用コールバック
sp->update = smsg_update;
}
@@ -234,10 +224,10 @@ void sp_set_wall_paper(int no) {
if (sp->curcg) { // display specified CG
sp->update = DEFAULT_UPDATE;
sp->cursize.width = sp->curcg->sf->width;
sp->cursize.height = sp->curcg->sf->height;
sp->width = sp->curcg->sf->w;
sp->height = sp->curcg->sf->h;
} else { // Black
sp->cursize.height = sf0->height;
sp->height = main_surface->h;
sp->curcg = NULL;
sp->update = sp_draw_wall;
}
@@ -289,7 +279,7 @@ void sp_free(int no) {
if (sp->type == SPRITE_MSG) {
slist_free(sp->u.msg.buf);
sf_free(sp->u.msg.canvas);
SDL_FreeSurface(sp->u.msg.canvas);
}
sact.updatelist = slist_remove(sact.updatelist, sp);
@@ -526,8 +516,8 @@ bool sp_query_size(int wNum, int *vw, int *vh) {
if (sp->type == SPRITE_NONE) goto errexit;
*vw = sp->cursize.width;
*vh = sp->cursize.height;
*vw = sp->width;
*vh = sp->height;
return true;
@@ -663,8 +653,8 @@ void sp_sound_ob(int wNumWave) {
bool sp_is_insprite(sprite_t *sp, int x, int y) {
uint8_t *dp;
if (x < 0 || y < 0 || x >= sf0->width || y >= sf0->height) return false;
if (x < 0 || y < 0 || x >= main_surface->w || y >= main_surface->h) return false;
dp = GETOFFSET_PIXEL(sact.dmap, x, y);
dp = PIXEL_AT(sact.dmap, x, y);
return (*(uint16_t *)dp == sp->no);
}
-4
View File
@@ -79,7 +79,6 @@ void sp_updateme_part(sprite_t *sp, int x, int y, int w, int h);
// in sprite_draw.c
void sp_draw(sprite_t *sf);
void sp_draw2(sprite_t *sf, cginfo_t *cg);
void sp_draw_dmap(void* data, void* userdata);
@@ -139,9 +138,6 @@ void sp_keywait(int *vOK, int *vRND, int *vRsv1, int *vRsv2, int *vRsv3, int tim
// in screen_quake.c
void sp_quake_screen(int type, int p1, int p2, int time, int cancel);
// in sactamask.c
void sp_eupdate_amap(int type, int time, int key);
// in sprite_xmenu.c
void spxm_clear(void);
void spxm_register(int reginum, int menuid);
+2 -3
View File
@@ -28,7 +28,6 @@
#include "portab.h"
#include "system.h"
#include "ags.h"
#include "sdl_core.h"
#include "sact.h"
#include "sprite.h"
@@ -44,7 +43,7 @@ static int eventCB_ANIM(sprite_t *sp, agsevent_t *e) {
if (e->type != AGSEVENT_TIMER) return 0;
// 現在時刻の取得
now = sdl_getTicks();
now = sys_get_ticks();
// 指定時間までスキップ
if ((now - sp->u.anime.starttime) < sp->u.anime.interval) return 0;
@@ -85,7 +84,7 @@ void sp_anime_setup(sprite_t *sp) {
int n = 0;
sp->u.anime.interval = 500; // デフォルトの間隔 0.5秒
sp->u.anime.starttime = sdl_getTicks(); // 開始時刻
sp->u.anime.starttime = sys_get_ticks(); // 開始時刻
sp->u.anime.tick = 0; // カウンタ初期化
// アニメパターンはいくつあるか
+39 -94
View File
@@ -23,56 +23,31 @@
#include "config.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <SDL.h>
#include "portab.h"
#include "system.h"
#include "ags.h"
#include "graphics.h"
#include "sact.h"
#include "surface.h"
#include "graph.h"
#include "ngraph.h"
#include "sprite.h"
static void fill_dmap(int dx ,int dy, int w, int h, uint16_t val);
static void fill_dmap_mask(surface_t *src, int sx, int sy, int dx ,int dy, int w, int h, uint16_t val);
// 矩形の depthmap を描画
static void fill_dmap(int dx ,int dy, int w, int h, uint16_t val) {
uint8_t *dp, *dp_;
int x, y;
dp = dp_ = (GETOFFSET_PIXEL(sact.dmap, dx, dy));
for (x = 0; x < w; x++) {
*((uint16_t *)dp + x) = val;
}
dp += sact.dmap->bytes_per_line;
for (y = 1; y < h; y++) {
memcpy(dp, dp_, w * 2);
dp += sact.dmap->bytes_per_line;
}
}
// alphamapにしたがって、alpha値が0より大きいところを指定のdepthとする
static void fill_dmap_mask(surface_t *src, int sx, int sy, int dx ,int dy, int w, int h, uint16_t val) {
static void fill_dmap_mask(SDL_Surface *src, int sx, int sy, int dx ,int dy, int w, int h, uint16_t val) {
uint8_t *sp, *dp;
int x, y;
dp = GETOFFSET_PIXEL(sact.dmap, dx, dy);
sp = GETOFFSET_ALPHA(src, sx, sy);
assert(src->format->Amask == 0xff000000);
dp = PIXEL_AT(sact.dmap, dx, dy);
sp = ALPHA_AT(src, sx, sy);
for (y = 0; y < h; y++) {
uint8_t *yls = (uint8_t *)(sp + y * src->width);
uint16_t *yld = (uint16_t *)(dp + y * sact.dmap->bytes_per_line);
uint8_t *yls = sp + y * src->pitch;
uint16_t *yld = (uint16_t *)(dp + y * sact.dmap->pitch);
for (x = 0; x < w; x++) {
if (*yls > 0) *yld = val;
yls++; yld++;
yls += 4; yld++;
}
}
}
@@ -83,57 +58,30 @@ static void fill_dmap_mask(surface_t *src, int sx, int sy, int dx ,int dy, int w
*/
void sp_draw(sprite_t *sp) {
if (sp == NULL) return;
sp_draw2(sp, sp->curcg);
}
/*
指定の spriteの指定のCGを surface0 に書く
(このインターフェイスはもう不要?)
@param sp: 描画するスプライト
@param cg: 描画するCG
*/
void sp_draw2(sprite_t *sp, cginfo_t *cg) {
surface_t update;
int sx, sy, w, h, dx, dy;
cginfo_t *cg = sp->curcg;
if (cg == NULL) return;
if (cg->sf == NULL) return;
// 更新領域の確定
update.width = sact.updaterect.w;
update.height = sact.updaterect.h;
sx = 0;
sy = 0;
dx = sp->cur.x - sact.updaterect.x;
dy = sp->cur.y - sact.updaterect.y;
w = cg->sf->width;
h = cg->sf->height;
if (!gr_clip(cg->sf, &sx, &sy, &w, &h, &update, &dx, &dy)) {
SDL_Rect cg_rect = {0, 0, cg->sf->w, cg->sf->h};
int sx = 0;
int sy = 0;
int dx = sp->cur.x;
int dy = sp->cur.y;
int w = cg->sf->w;
int h = cg->sf->h;
if (!ags_clipCopyRect(&cg_rect, &sact.updaterect, &sx, &sy, &dx, &dy, &w, &h)) {
return;
}
dx += sact.updaterect.x;
dy += sact.updaterect.y;
if (cg->sf->alpha) {
// alpha map がある場合
gre_BlendUseAMap(sf0, dx, dy,
sf0, dx, dy,
cg->sf, sx, sy, w, h,
cg->sf, sx, sy,
sp->blendrate);
if (SDL_ISPIXELFORMAT_ALPHA(cg->sf->format->format) || sp->blendrate < 255) {
SDL_SetSurfaceBlendMode(cg->sf, SDL_BLENDMODE_BLEND);
SDL_SetSurfaceAlphaMod(cg->sf, sp->blendrate);
} else {
if (sp->blendrate == 255) {
// alpha値指定が無い場合
gr_copy(sf0, dx, dy, cg->sf, sx, sy, w, h);
} else if (sp->blendrate > 0) {
// alpha値指定がある場合
gr_blend(sf0, dx, dy, cg->sf, sx, sy, w, h, sp->blendrate);
}
SDL_SetSurfaceBlendMode(cg->sf, SDL_BLENDMODE_NONE);
}
SDL_BlitSurface(cg->sf, &(SDL_Rect){sx, sy, w, h}, main_surface, &(SDL_Rect){dx, dy, w, h});
SACT_DEBUG("do update no=%d, sx=%d, sy=%d, w=%d, h=%d, dx=%d, dy=%d", sp->no, sx, sy, w, h, dx, dy);
}
@@ -143,38 +91,35 @@ void sp_draw2(sprite_t *sp, cginfo_t *cg) {
*/
void sp_draw_dmap(void* data, void* userdata) {
sprite_t *sp = (sprite_t *)data;
cginfo_t *cg;
surface_t update;
int sx, sy, w, h, dx, dy;
// 非表示状態の時は無視
if (!sp->show) return;
// ドラッグ中のスプライトは無視
if (sp == sact.draggedsp) return;
cg = sp->curcg;
cginfo_t *cg = sp->curcg;
if (cg == NULL) return;
if (cg->sf == NULL) return;
// depth map を書く領域を確定
update.width = sf0->width;
update.height = sf0->height;
sx = 0;
sy = 0;
dx = sp->cur.x;
dy = sp->cur.y;
w = cg->sf->width;
h = cg->sf->height;
if (!gr_clip(cg->sf, &sx, &sy, &w, &h, &update, &dx, &dy)) {
SDL_Rect cg_rect = {0, 0, cg->sf->w, cg->sf->h};
SDL_Rect screen_rect = {0, 0, main_surface->w, main_surface->h};
int sx = 0;
int sy = 0;
int dx = sp->cur.x;
int dy = sp->cur.y;
int w = cg->sf->w;
int h = cg->sf->h;
if (!ags_clipCopyRect(&cg_rect, &screen_rect, &sx, &sy, &dx, &dy, &w, &h)) {
return;
}
if (cg->sf->alpha) {
if (SDL_ISPIXELFORMAT_ALPHA(cg->sf->format->format)) {
fill_dmap_mask(cg->sf, sx, sy, dx, dy, w, h, sp->no);
} else {
fill_dmap(dx, dy, w, h, sp->no);
SDL_FillRect(sact.dmap, &(SDL_Rect){dx, dy, w, h}, sp->no);
}
return;
+11 -11
View File
@@ -25,12 +25,12 @@
#include "portab.h"
#include "system.h"
#include "ngraph.h"
#include "ags.h"
#include "input.h"
#include "sact.h"
#include "sprite.h"
#include "sdl_core.h"
#include "gfx.h"
#include "effect.h"
/*
効果つき画面更新
@@ -46,25 +46,25 @@ void sp_eupdate(int type, int time, int cancel) {
sp_update_all(false);
enum sdl_effect_type sdl_effect = from_sact_effect(type);
if (sdl_effect == EFFECT_INVALID) {
enum effect_type effect = from_sact_effect(type);
if (effect == EFFECT_INVALID) {
WARNING("Unimplemented effect %d", type);
type = EFFECT_CROSSFADE;
}
SDL_Rect rect = { 0, 0, sf0->width, sf0->height };
struct sdl_effect *eff = sdl_effect_init(&rect, NULL, 0, 0, sdl_getDIB(), 0, 0, sdl_effect);
SDL_Rect rect = { 0, 0, main_surface->w, main_surface->h };
struct effect *eff = effect_init(&rect, NULL, 0, 0, gfx_getDIB(), 0, 0, effect);
int sttime, curtime;
sttime = curtime = sdl_getTicks();
sttime = curtime = sys_get_ticks();
int edtime = curtime + time * 10;
while ((curtime = sdl_getTicks()) < edtime) {
sdl_effect_step(eff, (float)(curtime - sttime) / (edtime - sttime));
int rest = 16 - (sdl_getTicks() - curtime);
while ((curtime = sys_get_ticks()) < edtime) {
effect_step(eff, (float)(curtime - sttime) / (edtime - sttime));
int rest = 16 - (sys_get_ticks() - curtime);
int key = sys_keywait(rest, cancel ? KEYWAIT_CANCELABLE : KEYWAIT_NONCANCELABLE);
if (cancel && key)
break;
}
sdl_effect_finish(eff);
effect_finish(eff);
ags_updateFull();
}
+2 -3
View File
@@ -30,7 +30,6 @@
#include "portab.h"
#include "system.h"
#include "sdl_core.h"
#include "menu.h"
#include "input.h"
#include "nact.h"
@@ -213,7 +212,7 @@ static void cb_waitkey_simple(agsevent_t *e) {
switch (e->type) {
case AGSEVENT_KEY_PRESS:
if (e->code == KEY_Z) {
cur = sdl_getTicks();
cur = sys_get_ticks();
if (!sact.zhiding) {
slist_foreach(sact.sp_zhide, cb_defocused_zkey, &update);
sact.zhiding = true;
@@ -243,7 +242,7 @@ static void cb_waitkey_simple(agsevent_t *e) {
case AGSEVENT_KEY_RELEASE:
switch(e->code) {
case KEY_Z:
cur = sdl_getTicks();
cur = sys_get_ticks();
if (500 < (cur - sact.zofftime) || !sact.zdooff) {
slist_foreach(sact.sp_zhide, cb_focused_zkey, &update);
sact.zhiding = false;
+3 -6
View File
@@ -29,12 +29,9 @@
#include "portab.h"
#include "system.h"
#include "list.h"
#include "sdl_core.h"
#include "ags.h"
#include "nact.h"
#include "input.h"
#include "ngraph.h"
#include "surface.h"
#include "sact.h"
#include "sprite.h"
#include "sactsound.h"
@@ -69,7 +66,7 @@ static void hidesprite(sprite_t *sp) {
スプライトがドロップされた時の各種処理を含む
*/
static bool waitcond(int endtime) {
int curtime = sdl_getTicks();
int curtime = sys_get_ticks();
if (curtime >= endtime) return true;
if (sact.dropped) {
@@ -135,7 +132,7 @@ void sp_keywait(int *vOK, int *vRND, int *vD01, int *vD02, int *vD03, int timeou
{
// とりあえず、現在のマウス位置を送って、switch sprite の
// 状態を更新しておく
MyPoint p;
SDL_Point p;
sys_getMouseInfo(&p, false);
agsevent_t agse = {
.type = AGSEVENT_MOUSE_MOTION,
@@ -146,7 +143,7 @@ void sp_keywait(int *vOK, int *vRND, int *vD01, int *vD02, int *vD03, int timeou
}
// 終了時間の計算
curtime = sdl_getTicks();
curtime = sys_get_ticks();
endtime = timeout < 0 ? INT_MAX : (curtime + timeout * 10);
// スプライトキー待ちメイン
+3 -6
View File
@@ -32,7 +32,6 @@
#include "nact.h"
#include "sact.h"
#include "sprite.h"
#include "sdl_core.h"
/*
@@ -99,8 +98,6 @@ static int move_cb(sprite_t *sp, agsevent_t *e) {
// 新しい場所のupdate
sp_updateme(sp);
update++;
} else {
usleep(1);
}
return update;
@@ -161,14 +158,14 @@ void spev_move_waitend(sprite_t *sp, int dx, int dy, int time) {
sp->move.time = 0;
sact.movelist = slist_append(sact.movelist, sp);
sact.movestarttime = sdl_getTicks();
sact.movestarttime = sys_get_ticks();
slist_foreach(sact.movelist, spev_move_setup, NULL);
slist_free(sact.movelist);
sact.movelist = NULL;
while (sp->move.moving) {
nact->callback();
sdl_wait_vsync();
sys_wait_vsync();
}
}
@@ -187,7 +184,7 @@ void spev_wait4moving_sp() {
while (sp->move.moving) {
nact->callback();
sdl_wait_vsync();
sys_wait_vsync();
}
}
}
+26 -46
View File
@@ -29,13 +29,11 @@
#include "portab.h"
#include "system.h"
#include "sdl_core.h"
#include "ags.h"
#include "nact.h"
#include "input.h"
#include "sact.h"
#include "sprite.h"
#include "ngraph.h"
#include "drawtext.h"
#include "sactlog.h"
@@ -242,7 +240,7 @@ void smsg_out(int wNum, int wSize, int wColorR, int wColorG, int wColorB, int wF
sprite_t *sp;
int len = 0; // 処理した文字数?
bool needupdate = false;
MyRectangle uparea = {0,0,0,0};
SDL_Rect uparea = {0,0,0,0};
// wRSize == 0 -> ルビ無し(SACT.MessageOutputからの呼出)
@@ -269,7 +267,7 @@ void smsg_out(int wNum, int wSize, int wColorR, int wColorG, int wColorB, int wF
char mbuf[20], rbuf[20];
int cw, delta, wcnt;
wcnt = sdl_getTicks();
wcnt = sys_get_ticks();
mbuf[0] = rbuf[0] = '\0';
msg = get_char(msg, mbuf, rbuf, sizeof(mbuf) -1);
@@ -317,7 +315,7 @@ void smsg_out(int wNum, int wSize, int wColorR, int wColorG, int wColorB, int wF
needupdate = false;
// keywait
delta = sdl_getTicks() - wcnt;
delta = sys_get_ticks() - wcnt;
if (delta < wSpeed) {
if (sys_keywait(wSpeed - delta, KEYWAIT_NONCANCELABLE)) {
@@ -336,8 +334,8 @@ void smsg_out(int wNum, int wSize, int wColorR, int wColorG, int wColorB, int wF
// Waitなしの出力は最後にupdate
if (needupdate) {
uparea.w = sp->cursize.width;
uparea.h = min(sp->cursize.height, uparea.y - sp->u.msg.dspcur.y + wLineSpace + wLineSpace + wRSize);
uparea.w = sp->width;
uparea.h = min(sp->height, uparea.y - sp->u.msg.dspcur.y + wLineSpace + wLineSpace + wRSize);
sp_updateme_part(sp, uparea.x, uparea.y, uparea.w, uparea.h);
}
@@ -352,24 +350,19 @@ void smsg_out(int wNum, int wSize, int wColorR, int wColorG, int wColorB, int wF
@param wNum: クリアするスプライト番号
*/
void smsg_clear(int wNum) {
sprite_t *sp;
surface_t *sf;
if (!is_messagesprite(wNum)) return;
// 表示位置の初期化
sp = sact.sp[wNum];
sprite_t *sp = sact.sp[wNum];
sp->u.msg.dspcur.x = 0;
sp->u.msg.dspcur.y = 0;
sact.msgbuf[0] = '\0';
sact.msgbuf2[0] = '\0';
// キャンバスのクリア
sf = sp->u.msg.canvas;
memset(sf->pixel, 0, sf->bytes_per_line * sf->height);
memset(sf->alpha, 0, sf->width * sf->height);
// Clear the canvas
SDL_FillRect(sp->u.msg.canvas, NULL, 0);
sp_updateme(sp);
if (sact.logging) {
@@ -426,7 +419,7 @@ int smsg_keywait(int wNum1, int wNum2, int msglen) {
sact.waitkey = -1;
while (sact.waitkey == -1 && !nact->is_quit) {
int st = sdl_getTicks();
int st = sys_get_ticks();
int interval = 25;
// アニメパターンがある場合、その更新
@@ -440,7 +433,7 @@ int smsg_keywait(int wNum1, int wNum2, int msglen) {
update_mark(minfo[j].sp, minfo[j].cg);
i++;
}
sys_keywait(interval - (sdl_getTicks() - st), KEYWAIT_NONCANCELABLE);
sys_keywait(interval - (sys_get_ticks() - st), KEYWAIT_NONCANCELABLE);
}
sact.waittype = KEYWAIT_NONE;
@@ -453,32 +446,19 @@ int smsg_keywait(int wNum1, int wNum2, int msglen) {
@param sp: 再描画するスプライト
*/
void smsg_update(sprite_t *sp) {
int sx, sy, w, h, dx, dy;
surface_t update;
// canvas が clean のときはなにもしない
// -> 説明スプライトのように、SetShowされたときに対応できないからだめ
//if (sact.msgbufempty) return;
update.width = sact.updaterect.w;
update.height = sact.updaterect.h;
dx = sp->cur.x - sact.updaterect.x;
dy = sp->cur.y - sact.updaterect.y;
w = sp->cursize.width;
h = sp->cursize.height;
sx = 0; sy = 0;
if (!gr_clip(sp->u.msg.canvas, &sx, &sy, &w, &h, &update, &dx, &dy)) {
SDL_Rect sp_rect = {0, 0, sp->width, sp->height};
int sx = 0;
int sy = 0;
int dx = sp->cur.x;
int dy = sp->cur.y;
int w = sp->width;
int h = sp->height;
if (!ags_clipCopyRect(&sp_rect, &sact.updaterect, &sx, &sy, &dx, &dy, &w, &h)) {
return;
}
dx += sact.updaterect.x;
dy += sact.updaterect.y;
gre_BlendUseAMap(sf0, dx, dy, sf0, dx, dy, sp->u.msg.canvas, sx, sy, w, h, sp->u.msg.canvas, sx, sy, sp->blendrate);
SDL_SetSurfaceBlendMode(sp->u.msg.canvas, SDL_BLENDMODE_BLEND);
SDL_SetSurfaceAlphaMod(sp->u.msg.canvas, sp->blendrate);
SDL_BlitSurface(sp->u.msg.canvas, &(SDL_Rect){sx, sy, w, h}, main_surface, &(SDL_Rect){dx, dy, w, h});
SACT_DEBUG("do update no=%d, sx=%d, sy=%d, w=%d, h=%d, dx=%d, dy=%d",
sp->no, sx, sy, w, h, dx, dy);
@@ -553,7 +533,7 @@ static void append_to_log(char *msg) {
static void sactlog_newline() {
if (sact.logging) {
if (sact.msgbuf2[0] == '\0') return;
sact.log = list_append(sact.log, strdup(sact.msgbuf2));
sact.log = list_append(sact.log, toUTF8(sact.msgbuf2));
sact.msgbuf2[0] = '\0';
}
}
@@ -566,10 +546,10 @@ static void set_align(char *msg, sprite_t *sp, int wSize, int wAlign) {
switch (wAlign) {
case 1: // センタリング
adjx = (sp->cursize.width - mlen) / 2;
adjx = (sp->width - mlen) / 2;
break;
case 2: // 右寄せ
adjx = (sp->cursize.width - mlen);
adjx = (sp->width - mlen);
break;
}
sp->u.msg.dspcur.x = max(0, adjx);
+2 -5
View File
@@ -30,10 +30,7 @@
#include "list.h"
#include "input.h"
#include "sact.h"
#include "surface.h"
#include "ngraph.h"
#include "sprite.h"
#include "sdl_core.h"
#include "randMT.h"
/*
@@ -51,9 +48,9 @@ void sp_quake_sprite(int wType, int wAmplitudeX, int wAmplitudeY, int wCount, in
int i = 0, key;
SList *node;
edtime = wCount * 10 + sdl_getTicks();
edtime = wCount * 10 + sys_get_ticks();
while ((curtime = sdl_getTicks()) < edtime) {
while ((curtime = sys_get_ticks()) < edtime) {
if (wType == 0) { // 全てのスプライトを同じように動かす
int adjx = (int)(genrand() * wAmplitudeX/2);
int adjy = (int)(genrand() * wAmplitudeY/2);
+27 -28
View File
@@ -26,6 +26,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <SDL.h>
#include "portab.h"
#include "nact.h"
@@ -33,16 +34,12 @@
#include "input.h"
#include "sact.h"
#include "sprite.h"
#include "ngraph.h"
#include "drawtext.h"
// 選択された要素(1~) キャンセルの場合は0、初期状態は -1
static int selected_item;
static int selected_item_cur;
// 選択肢を描画するsurface
static surface_t *selcanvas;
// 前のカーソルの状態
static bool oldstate; // spriteの中か外か
static int oldindex; // 何番目の要素か(0~)
@@ -63,12 +60,12 @@ static int sel_main();
* マージン内はsprite内部とは判断しない
*/
static bool sp_is_insprite2(sprite_t *sp, int x, int y, int margin) {
MyPoint p = {x, y};
MyRectangle r = {
SDL_Point p = {x, y};
SDL_Rect r = {
sp->cur.x + margin,
sp->cur.y + margin,
sp->curcg->sf->width - 2 * margin,
sp->curcg->sf->height - 2 * margin
sp->curcg->sf->w - 2 * margin,
sp->curcg->sf->h - 2 * margin
};
return SDL_PointInRect(&p, &r);
}
@@ -141,6 +138,17 @@ static void cb_select_release(agsevent_t *e) {
}
}
static void draw_box(SDL_Surface *dst, int x, int y, int w, int h) {
SDL_FillRect(dst, &(SDL_Rect){x, y, w, h}, SDL_MapRGB(dst->format, 0, 0, 0));
SDL_Rect border_rects[4] = {
{x, y, w, 1},
{x, y + h - 1, w, 1},
{x, y, 1, h},
{x + w - 1, y, 1, h}
};
SDL_FillRects(dst, border_rects, 4, SDL_MapRGB(dst->format, 255, 255, 255));
}
// 選択ウィンドを更新するときの callback
static void update_selwindow(sprite_t *sp) {
int selno = selected_item_cur;
@@ -153,18 +161,16 @@ static void update_selwindow(sprite_t *sp) {
// 選択されている要素
if (selno && sact.sel.elem[selno] != NULL) {
int w = selcanvas->width - 2 * sact.sel.frame_dot;
int w = sact.sel.charcanvas->w - 2 * sact.sel.frame_dot;
int h = sact.sel.font_size + sact.sel.linespace;
int x = x0 + sact.sel.frame_dot;
int y = y0 + sact.sel.frame_dot + (selno -1) * h;
gr_fill(sf0, x, y, w, h, 0, 0, 0);
gr_drawrect(sf0, x, y, w, h, 255, 255, 255);
draw_box(main_surface, x, y, w, h);
}
// 選択肢文字列
gr_expandcolor_blend(sf0, x0, y0,
sact.sel.charcanvas, 0, 0,
selcanvas->width, selcanvas->height, 255, 255, 255);
SDL_BlitSurface(sact.sel.charcanvas, NULL, main_surface,
&(SDL_Rect){x0, y0, sact.sel.charcanvas->w, sact.sel.charcanvas->h});
}
// 選択ウィンドの準備
@@ -172,11 +178,9 @@ static void setup_selwindow() {
sprite_t *sp = sact.sp[sact.sel.spno];
int i;
//選択ウィンド作業 surfaceの生成
selcanvas = sf_dup(sp->cg1->sf);
// 選択肢文字用 canvas
sact.sel.charcanvas = sf_create_pixel(selcanvas->width, selcanvas->height, 8);
sact.sel.charcanvas = SDL_CreateRGBSurfaceWithFormat(0, sp->cg1->sf->w, sp->cg1->sf->h, 32, SDL_PIXELFORMAT_ARGB8888);
SDL_SetSurfaceBlendMode(sact.sel.charcanvas, SDL_BLENDMODE_BLEND);
dt_setfont(sact.sel.font_type, sact.sel.font_size);
@@ -187,9 +191,9 @@ static void setup_selwindow() {
// 文字の場所計算
x = 0; // 行そろえは無し
y = (i - 1) * (sact.sel.font_size + sact.sel.linespace);
dt_drawtext(sact.sel.charcanvas,
dt_drawtext_col(sact.sel.charcanvas,
x + sact.sel.frame_dot, y + sact.sel.frame_dot,
sact.sel.elem[i]);
sact.sel.elem[i], 255, 255, 255);
}
// デフォルトで選択される選択肢がある場合、そこへカーソルを移動
@@ -222,9 +226,8 @@ static void remove_selwindow() {
sp_update_clipped();
// 作業用 surface の削除
sf_free(selcanvas);
selcanvas = NULL;
sf_free(sact.sel.charcanvas);
if (sact.sel.charcanvas)
SDL_FreeSurface(sact.sel.charcanvas);
sact.sel.charcanvas = NULL;
}
@@ -261,12 +264,8 @@ void ssel_init() {
void ssel_reset(void) {
ssel_clear();
if (selcanvas) {
sf_free(selcanvas);
selcanvas = NULL;
}
if (sact.sel.charcanvas) {
sf_free(sact.sel.charcanvas);
SDL_FreeSurface(sact.sel.charcanvas);
sact.sel.charcanvas = NULL;
}
}
+1 -2
View File
@@ -33,7 +33,6 @@
#include "nact.h"
#include "sact.h"
#include "sprite.h"
#include "sdl_core.h"
/*
@@ -63,7 +62,7 @@ static void tevent_callback(agsevent_t *e) {
int update = 0;
// SP_MOVE の同期移動のためのカウンタの読み込み
sact.movecurtime = sdl_getTicks();
sact.movecurtime = sys_get_ticks();
for (node = sact.teventlisteners; node; node = node->next) {
sprite_t *sp = (sprite_t *)node->data;
+15 -19
View File
@@ -28,12 +28,8 @@
#include "portab.h"
#include "system.h"
#include "sdl_core.h"
#include "ags.h"
#include "graphics.h"
#include "sact.h"
#include "surface.h"
#include "ngraph.h"
#include "sprite.h"
// スプライト再描画間の間に変更のあったスプライトの領域の和
@@ -45,16 +41,16 @@ static void do_update_each(void* data, void* userdata);
// 領域1と領域2をすべて含む矩形領域を計算
static void disjunction(void* region, void* data) {
MyRectangle *r1 = (MyRectangle *)region;
MyRectangle *r2 = (MyRectangle *)data;
SDL_Rect *r1 = (SDL_Rect *)region;
SDL_Rect *r2 = (SDL_Rect *)data;
SDL_UnionRect(r1, r2, r2);
free(r1);
}
// 更新の必要なスプライトの領域の和をとってクリッピングする
static void get_updatearea() {
MyRectangle clip = {0, 0, 0, 0};
MyRectangle rsf0 = {0, 0, sf0->width, sf0->height};
SDL_Rect clip = {0, 0, 0, 0};
SDL_Rect screen = {0, 0, main_surface->w, main_surface->h};
slist_foreach(updatearea, disjunction, &clip);
@@ -62,7 +58,7 @@ static void get_updatearea() {
updatearea = NULL;
// surface0との領域の積をとる
SDL_IntersectRect(&rsf0, &clip, &sact.updaterect);
SDL_IntersectRect(&screen, &clip, &sact.updaterect);
SACT_DEBUG("clipped area x=%d y=%d w=%d h=%d",
sact.updaterect.x, sact.updaterect.y,
@@ -95,7 +91,7 @@ void sp_update_all(bool syncscreen) {
// スプライト移動がある場合は移動開始
if (sact.movelist) {
// 移動開始時間を合わせる
sact.movestarttime = sdl_getTicks();
sact.movestarttime = sys_get_ticks();
slist_foreach(sact.movelist, spev_move_setup, NULL);
slist_free(sact.movelist);
sact.movelist = NULL;
@@ -104,8 +100,8 @@ void sp_update_all(bool syncscreen) {
// 画面全体を更新領域に
sact.updaterect.x = 0;
sact.updaterect.y = 0;
sact.updaterect.w = sf0->width;
sact.updaterect.h = sf0->height;
sact.updaterect.w = main_surface->w;
sact.updaterect.h = main_surface->h;
// updatelistに登録してあるスプライトを再描画
// updatelistはスプライトの番号順に並んでいる
@@ -151,16 +147,16 @@ void sp_update_clipped() {
@param sp: 更新するスプライト
*/
void sp_updateme(sprite_t *sp) {
MyRectangle *r;
SDL_Rect *r;
if (sp == NULL) return;
if (sp->cursize.width == 0 || sp->cursize.height == 0) return;
if (sp->width == 0 || sp->height == 0) return;
r = malloc(sizeof(MyRectangle));
r = malloc(sizeof(SDL_Rect));
r->x = sp->cur.x;
r->y = sp->cur.y;
r->w = sp->cursize.width;
r->h = sp->cursize.height;
r->w = sp->width;
r->h = sp->height;
updatearea = slist_append(updatearea, r);
@@ -177,12 +173,12 @@ void sp_updateme(sprite_t *sp) {
@param h: 更新領域高さ
*/
void sp_updateme_part(sprite_t *sp, int x, int y, int w, int h) {
MyRectangle *r;
SDL_Rect *r;
if (sp == NULL) return;
if (w == 0 || h == 0) return;
r = malloc(sizeof(MyRectangle));
r = malloc(sizeof(SDL_Rect));
r->x = sp->cur.x + x;
r->y = sp->cur.y + y;
r->w = w;
+25 -98
View File
@@ -36,15 +36,12 @@
#include "nact.h"
#include "ags.h"
#include "music.h"
#include "sdl_core.h"
#include "hacks.h"
#define SLOT 40
static void copy_sprite(int sx, int sy, int width, int height, int dx, int dy, int r, int g, int b);
static MyRectangle maprect; /* アニメーション表示領域 */
static MyRectangle mapback; /* 背景セーブ領域 */
static SDL_Rect maprect; /* アニメーション表示領域 */
static SDL_Rect mapback; /* 背景セーブ領域 */
static int mapback_p5; /* 背景転送先 X */
static int mapback_p6; /* 背景転送先 Y */
@@ -89,6 +86,14 @@ static struct _s2 s2[SLOT];
static int* add_p5[SLOT]; /* どこまでアニメーションのコマが進んだか */
static void copy_sprite(int sx, int sy, int width, int height, int dx, int dy, int r, int g, int b) {
SDL_Surface *sf = nact->ags.dib->sdl_surface;
SDL_SetColorKey(sf, SDL_TRUE, SDL_MapRGB(sf->format, r, g, b));
SDL_Rect src_rect = { sx, sy, width, height };
SDL_Rect dst_rect = { dx, dy, width, height };
SDL_BlitSurface(sf, &src_rect, sf, &dst_rect);
SDL_SetColorKey(sf, SDL_FALSE, 0);
}
static void Init() {
/*
@@ -135,7 +140,7 @@ static void ChangeNotColor() {
int *src = getCaliVariable(); /* r, g, b */
int *dst = getCaliVariable(); /* r, g, b */
int p7 = getCaliValue(); /* ISurface */
agsurface_t *dib;
surface_t *dib;
int x, y;
uint8_t *dp;
@@ -146,42 +151,18 @@ static void ChangeNotColor() {
dib = nact->ags.dib;
dp = GETOFFSET_PIXEL(dib, x0, y0);
switch(dib->depth) {
case 16:
{
uint16_t pic16s = PIX16(*src, *(src+1), *(src+2));
uint16_t pic16d = PIX16(*dst, *(dst+1), *(dst+2));
uint16_t *yl;
for (y = 0; y < height; y++) {
yl = (uint16_t *)(dp + y * dib->bytes_per_line);
for (x = 0; x < width; x++) {
if (*yl != pic16s) {
*yl = pic16d;
}
yl++;
uint32_t pic24s = PIX24(*src, *(src+1), *(src+2));
uint32_t pic24d = PIX24(*dst, *(dst+1), *(dst+2));
uint32_t *yl;
for (y = 0; y < height; y++) {
yl = (uint32_t *)(dp + y * dib->sdl_surface->pitch);
for (x = 0; x < width; x++) {
if (*yl != pic24s) {
*yl = pic24d;
}
yl++;
}
break;
}
case 24:
case 32:
{
uint32_t pic24s = PIX24(*src, *(src+1), *(src+2));
uint32_t pic24d = PIX24(*dst, *(dst+1), *(dst+2));
uint32_t *yl;
for (y = 0; y < height; y++) {
yl = (uint32_t *)(dp + y * dib->bytes_per_line);
for (x = 0; x < width; x++) {
if (*yl != pic24s) {
*yl = pic24d;
}
yl++;
}
}
break;
}
}
// The CX command after ChangeNotColor (in FIGHT.ADV) must use a precise
// calculation.
@@ -453,7 +434,7 @@ static void PlayAnimeData() {
int interval, loop;
int i;
bool is_backcopied;
agsurface_t *dib;
surface_t *dib;
TRACE("ShGraph.PlayAnimeData %d,%d,%d,%d,%d,%d:", p1, p2, p3, p4, p5, p6);
@@ -469,7 +450,7 @@ static void PlayAnimeData() {
dib = ags_getDIB();
for (loop = 0; loop < p1; loop++) {
int cnt = sdl_getTicks();
int cnt = sys_get_ticks();
is_backcopied = false;
for (i = 0; i < SLOT; i++) {
@@ -546,67 +527,13 @@ static void PlayAnimeData() {
if (is_backcopied && !SDL_RectEmpty(&maprect))
ags_updateArea(maprect.x, maprect.y, maprect.w, maprect.h);
int now = sdl_getTicks();
int now = sys_get_ticks();
if (now - cnt < interval) {
sdl_sleep(interval - (now-cnt));
sys_sleep(interval - (now-cnt));
}
}
}
static void copy_sprite(int sx, int sy, int width, int height, int dx, int dy, int r, int g, int b) {
int x, y;
uint8_t *sp, *dp;
agsurface_t *dib;
if (dx < 0 || dy < 0) return;
ags_check_param(&sx, &sy, &width, &height);
ags_check_param(&dx, &dy, &width, &height);
dib = nact->ags.dib;
sp = GETOFFSET_PIXEL(dib, sx, sy);
dp = GETOFFSET_PIXEL(dib, dx, dy);
switch(dib->depth) {
case 16:
{
uint16_t pic16 = PIX16(r, g, b);
uint16_t *yls, *yld;
for (y = 0; y < height; y++) {
yls = (uint16_t *)(sp + y * dib->bytes_per_line);
yld = (uint16_t *)(dp + y * dib->bytes_per_line);
for (x = 0; x < width; x++) {
if (*yls != pic16) {
*yld = *yls;
}
yls++; yld++;
}
}
break;
}
case 24:
case 32:
{
uint32_t pic24 = PIX24(r, g, b);
uint32_t *yls, *yld;
for (y = 0; y < height; y++) {
yls = (uint32_t *)(sp + y * dib->bytes_per_line);
yld = (uint32_t *)(dp + y * dib->bytes_per_line);
for (x = 0; x < width; x++) {
if (*yls != pic24) {
*yld = *yls;
}
yls++; yld++;
}
}
break;
}
}
}
static const ModuleFunc functions[] = {
{"AddAnimeData", AddAnimeData},
{"AddAnimeRemain", AddAnimeRemain},
+1 -2
View File
@@ -35,7 +35,6 @@
#include "system.h"
#include "xsystem35.h"
#include "modules.h"
#include "sdl_core.h"
#include "input.h"
#include "menu.h"
@@ -54,7 +53,7 @@ static void OutputMessageBox(void) { /* 0 */
char *title_utf8 = toUTF8(svar_get(title));
char *msg_utf8 = toUTF8(svar_get(msg));
sdl_showMessageBox(MESSAGEBOX_INFO, title_utf8, msg_utf8);
sys_show_message_box(MESSAGEBOX_INFO, title_utf8, msg_utf8);
free(title_utf8);
free(msg_utf8);
+7 -45
View File
@@ -30,8 +30,6 @@
#include "nact.h"
#include "ags.h"
#include "font.h"
#include "surface.h"
#include "ngraph.h"
static FontType ftype;
static int fsize; // フォントの大きさ
@@ -54,33 +52,6 @@ void dt_setfont(FontType type, int size) {
fsize = size;
}
/**
* surface にモノクロ文字を描画。アンチエイリアスされており256階調
* 書き出すsurfaceは8ビットである必要あり
*
* @param sf: 描画する surface
* @param x: 描画位置X座標
* @param y: 描画位置Y座標
* @param buf: 描画文字列 (SJIS)
* @return: 実際に描画した幅
*/
int dt_drawtext(surface_t *sf, int x, int y, char *buf) {
int sx, sy, sw, sh;
ags_setFont(ftype, fsize);
agsurface_t *glyph = ags_drawStringToSurface(buf);
if (glyph == NULL) return 0;
sx = x; sy = y;
sw = glyph->width;
sh = glyph->height;
if (!gr_clip_xywh(sf, &sx, &sy, &sw, &sh)) return 0;
gr_copy(sf, sx, sy, glyph, 0, 0, sw, sh);
return sw;
}
/**
* surface にカラー文字を描画。alphamap に256階調のアンチエイリアスされた
* 文字を描き、pixelmap には、色情報を矩形で描く
@@ -94,23 +65,14 @@ int dt_drawtext(surface_t *sf, int x, int y, char *buf) {
* @param b: 文字色青
* @return: 実際に描画した幅
*/
int dt_drawtext_col(surface_t *sf, int x, int y, char *buf, int r, int g, int b) {
int sx, sy, sw, sh;
int dt_drawtext_col(SDL_Surface *sf, int x, int y, char *buf, int r, int g, int b) {
ags_setFont(ftype, fsize);
agsurface_t *glyph = ags_drawStringToSurface(buf);
SDL_Surface *glyph = ags_drawStringToSurface(buf, r, g, b);
if (glyph == NULL) return 0;
sx = x; sy = y;
sw = glyph->width;
sh = glyph->height;
if (!gr_clip_xywh(sf, &sx, &sy, &sw, &sh)) return 0;
// alpha map に文字そのものを描く
gr_draw_amap(sf, sx, sy, glyph->pixel, sw, sh, glyph->bytes_per_line);
// pixel map には色情報を矩形で描く
gr_fill(sf, sx, sy, sw, sh, r, g, b);
return sw;
SDL_Rect rect = {x, y, glyph->w, glyph->h};
SDL_SetSurfaceBlendMode(glyph, SDL_BLENDMODE_NONE);
SDL_BlitSurface(glyph, NULL, sf, &rect);
SDL_FreeSurface(glyph);
return rect.w;
}
+4 -3
View File
@@ -24,10 +24,11 @@
#ifndef __DRAWTEXT_H__
#define __DRAWTEXT_H__
#include "graphics.h"
#include "font.h"
struct SDL_Surface;
void dt_setfont(FontType type, int size);
int dt_drawtext(surface_t *sf, int x, int y, char *buf);
int dt_drawtext_col(surface_t *sf, int x, int y, char *buf, int r, int g, int b);
int dt_drawtext_col(struct SDL_Surface *sf, int x, int y, char *buf, int r, int g, int b);
#endif /* __DRAWTEXT_H__ */
-19
View File
@@ -1,19 +0,0 @@
#ifndef __GRAPH_H__
#define __GRAPH_H__
#include "config.h"
#include "surface.h"
extern void gr_init();
extern void gr_blend(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int width, int height, int lv);
extern void gr_blend_screen(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int width, int height);
extern void gr_copy_stretch_blend_alpha_map(surface_t *dst, int dx, int dy, int dw, int dh, surface_t *src, int sx, int sy, int sw, int sh);
extern void gr_fill_alpha_overborder(surface_t *dst, int dx, int dy, int dw, int dh, int s, int d);
extern void gr_fill_alpha_underborder(surface_t *dst, int dx, int dy, int dw, int dh, int s, int d);
extern void gr_copy_alpha_map_sprite(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int sw, int sh, int cl);
extern void gr_blend_alpha_wds_stretch2x2(surface_t *src1, int sx1, int sy1, surface_t *src2, int sx2, int sy2, int sw, int sh, surface_t *dst, int dx, int dy);
extern void gr_blend_alpha_wds(surface_t *src1, int sx1, int sy1, surface_t *src2, int sx2, int sy2, int sw, int sh, surface_t *dst, int dx, int dy);
#endif /* __GRAPH_H__ */
+39 -4
View File
@@ -5,19 +5,54 @@
#include "portab.h"
#include "system.h"
#include "surface.h"
#include "ngraph.h"
#include "graph_blend_amap.h"
#include "ags.h"
static void gre_BlendUseAMap(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int width, int height) {
uint8_t *sp = GETOFFSET_PIXEL(src, sx, sy);
uint8_t *dp = GETOFFSET_PIXEL(dst, dx, dy);
uint8_t *ap = GETOFFSET_ALPHA(src, sx, sy);
switch (dst->sdl_surface->format->BitsPerPixel) {
case 16:
for (int y = 0; y < height; y++) {
uint16_t *yls = (uint16_t *)(sp + y * src->sdl_surface->pitch);
uint16_t *yld = (uint16_t *)(dp + y * dst->sdl_surface->pitch);
uint8_t *yla = (uint8_t *)(ap + y * src->width);
for (int x = 0; x < width; x++) {
*yld = ALPHABLEND16(*yls, *yld, *yla);
yls++; yld++; yla++;
}
}
break;
case 24:
case 32:
for (int y = 0; y < height; y++) {
uint32_t *yls = (uint32_t *)(sp + y * src->sdl_surface->pitch);
uint32_t *yld = (uint32_t *)(dp + y * dst->sdl_surface->pitch);
uint8_t *yla = (uint8_t *)(ap + y * src->width);
for (int x = 0; x < width; x++) {
*yld = ALPHABLEND24(*yls, *yld, *yla);
yls++; yld++; yla++;
}
}
break;
}
}
void gr_blend_alpha_map(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int sw, int sh) {
if (src == NULL || dst == NULL) return;
if (!gr_clip(src, &sx, &sy, &sw, &sh, dst, &dx, &dy)) return;
SDL_Rect src_window = { 0, 0, src->width, src->height };
SDL_Rect dst_window = { 0, 0, dst->width, dst->height };
if (!ags_clipCopyRect(&src_window, &dst_window, &sx, &sy, &dx, &dy, &sw, &sh)) return;
if (src->alpha == NULL) {
WARNING("src alpha NULL");
return;
}
gre_BlendUseAMap(dst, dx, dy, dst, dx, dy, src, sx, sy, sw, sh, src, sx, sy, 255);
gre_BlendUseAMap(dst, dx, dy, src, sx, sy, sw, sh);
}
+8
View File
@@ -0,0 +1,8 @@
#ifndef __GRAPH_BLEND_AMAP_H__
#define __GRAPH_BLEND_AMAP_H__
#include "ags.h"
void gr_blend_alpha_map(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int sw, int sh);
#endif /* __GRAPH_BLEND_AMAP_H__ */
-42
View File
@@ -1,42 +0,0 @@
// srcのsurfaceの一部をdstに飽和加算
#include <stdio.h>
#include "portab.h"
#include "system.h"
#include "surface.h"
#include "ngraph.h"
#include "ags.h"
void gr_blend_screen(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int width, int height) {
if (!gr_clip(src, &sx, &sy, &width, &height, dst, &dx, &dy)) return;
uint8_t *sp = GETOFFSET_PIXEL(src, sx, sy);
uint8_t *dp = GETOFFSET_PIXEL(dst, dx, dy);
switch(dst->depth) {
case 16:
for (int y = 0; y < height; y++) {
uint16_t *yls = (uint16_t *)(sp + y * src->bytes_per_line);
uint16_t *yld = (uint16_t *)(dp + y * dst->bytes_per_line);
for (int x = 0; x < width; x++) {
*yld = SUTURADD16(*yls, *yld);
yls++; yld++;
}
}
break;
case 32:
case 24:
for (int y = 0; y < height; y++) {
uint32_t *yls = (uint32_t *)(sp + y * src->bytes_per_line);
uint32_t *yld = (uint32_t *)(dp + y * dst->bytes_per_line);
for (int x = 0; x < width; x++) {
*yld = SUTURADD24(*yls, *yld);
yls++; yld++;
}
}
break;
}
}
-150
View File
@@ -1,150 +0,0 @@
/*
* graph_cg.c surface に 実際にcgデータを描く
*
* Copyright (C) 1997-1998 Masaki Chikama (Wren) <chikama@kasumi.ipl.mech.nagoya-u.ac.jp>
* 1998- <masaki-c@is.aist-nara.ac.jp>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/* $Id: graph_cg.c,v 1.2 2003/08/30 21:29:16 chikama Exp $ */
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include "portab.h"
#include "surface.h"
#include "cg.h"
#include "ags.h"
#include "ngraph.h"
/**
* surface に 24bpp CG (QNT)を描画
*
* @param ds: 描画 surface
* @param cg: 描画するCGデータ
* @param x: 描画X座標
* @param y: 描画Y座標
*/
void gr_drawimage24(surface_t *ds, cgdata *cg, int x, int y) {
int dx, dy, dw, dh;
uint8_t *sp, *dp, r, g, b;
dx = x;
dy = y;
dw = cg->width;
dh = cg->height;
if (!gr_clip_xywh(ds, &dx, &dy, &dw, &dh)) return;
int data_offset = (abs(dy - y) * cg->width + abs(dx - x)) * 3;
sp = (uint8_t *)(cg->pic + data_offset);
dp = GETOFFSET_PIXEL(ds, dx, dy);
switch(ds->depth) {
case 16:
{
uint16_t *yl;
for (y = 0; y < dh; y++) {
yl = (uint16_t *)(dp + y * ds->bytes_per_line);
for (x = 0; x < dw; x++) {
r = *sp;
g = *(sp +1);
b = *(sp +2);
*yl = PIX16(r, g, b);
yl++; sp += 3;
}
sp += ((cg->width - dw) * 3);
}
break;
}
case 24:
case 32:
{
uint32_t *yl;
for (y = 0; y < dh; y++) {
yl = (uint32_t *)(dp + y * ds->bytes_per_line);
for (x = 0; x < dw; x++) {
r = *sp;
g = *(sp +1);
b = *(sp +2);
*yl = PIX24(r, g, b);
yl++; sp += 3;
}
sp += ((cg->width - dw) * 3);
}
break;
}}
}
/**
* surface に 16bpp CG (PMS16/BMP)を描画
*
* @param ds: 描画 surface
* @param cg: 描画するCGデータ
* @param x: 描画X座標
* @param y: 描画Y座標
*/
void gr_drawimage16(surface_t *ds, cgdata *cg, int x, int y) {
int dx, dy, dw, dh;
uint8_t *dp;
uint16_t pic16, *sp;
dx = x;
dy = y;
dw = cg->width;
dh = cg->height;
if (!gr_clip_xywh(ds, &dx, &dy, &dw, &dh)) return;
int data_offset = (abs(dy - y) * cg->width + abs(dx - x)) * 2;
sp = (uint16_t *)(cg->pic + data_offset);
dp = GETOFFSET_PIXEL(ds, dx, dy);
switch(ds->depth) {
case 16:
{
for (y = 0; y < dh; y++) {
memcpy(dp, sp, dw * 2);
sp += cg->width;
dp += ds->bytes_per_line;
}
break;
}
case 24:
case 32:
{
uint32_t *yl;
for (y = 0; y < dh; y++) {
yl = (uint32_t *)(dp + y * ds->bytes_per_line);
for (x = 0; x < dw; x++) {
pic16 = *sp;
*yl = rgb565_to_rgb888(pic16);
yl++; sp++;
}
sp += (cg->width - dw);
}
break;
}}
}
-78
View File
@@ -1,78 +0,0 @@
/*
* graph_copy.c pixel データのコピー
*
* Copyright (C) 1997-1998 Masaki Chikama (Wren) <chikama@kasumi.ipl.mech.nagoya-u.ac.jp>
* 1998- <masaki-c@is.aist-nara.ac.jp>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/* $Id: graph_copy.c,v 1.2 2003/04/25 17:23:55 chikama Exp $ */
#include <string.h>
#include "portab.h"
#include "surface.h"
#include "ngraph.h"
#include "ags.h"
/**
* 指定の surface の領域を 別の surface の指定位置へコピーする
* pixelデータのみコピー
*
* @param dst: 転送先 surface
* @param dx: 転送先X座標
* @param dy: 転送先Y座標
* @param src: 転送元surface
* @param sx: 転送元X座標
* @param sy: 転送元Y座標
* @param sw: 転送幅
* @param sh: 転送高さ
*/
void gr_copy(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int sw, int sh) {
uint8_t *sp, *dp;
if (src == NULL || dst == NULL) return;
if (!gr_clip(src, &sx, &sy, &sw, &sh, dst, &dx, &dy)) return;
sp = GETOFFSET_PIXEL(src, sx, sy);
dp = GETOFFSET_PIXEL(dst, dx, dy);
if (sp == NULL || dp == NULL) return;
if (src == dst) {
if (sy <= dy && dy < (sy + sh)) {
sp += (sh -1) * src->bytes_per_line;
dp += (sh -1) * dst->bytes_per_line;
while(sh--) {
memmove(dp, sp, sw * src->bytes_per_pixel);
sp -= src->bytes_per_line;
dp -= dst->bytes_per_line;
}
} else {
while(sh--) {
memmove(dp, sp, sw * src->bytes_per_pixel);
sp += src->bytes_per_line;
dp += dst->bytes_per_line;
}
}
} else {
while(sh--) {
memcpy(dp, sp, sw * src->bytes_per_pixel);
sp += src->bytes_per_line;
dp += dst->bytes_per_line;
}
}
}
-55
View File
@@ -1,55 +0,0 @@
// 指定のsurface領域を明るさを lv/255 倍してコピー
#include <string.h>
#include "portab.h"
#include "surface.h"
#include "ngraph.h"
#include "ags.h"
void gr_copy_bright(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int width, int height, int lv) {
int x, y;
uint8_t *sp, *dp;
if (!gr_clip(src, &sx, &sy, &width, &height, dst, &dx, &dy)) return;
sp = GETOFFSET_PIXEL(src, sx, sy);
dp = GETOFFSET_PIXEL(dst, dx, dy);
if (sp == NULL || dp == NULL) return;
switch(dst->depth) {
case 16:
{
uint16_t *yls, *yld;
for (y = 0; y < height; y++) {
yls = (uint16_t *)(sp + y * src->bytes_per_line);
yld = (uint16_t *)(dp + y * dst->bytes_per_line);
for (x = 0; x < width; x++) {
*yld = ALPHALEVEL16(*yls, lv);
yls++; yld++;
}
}
}
break;
case 24:
case 32:
{
uint32_t *yls, *yld;
for (y = 0; y < height; y++) {
yls = (uint32_t *)(sp + y * src->bytes_per_line);
yld = (uint32_t *)(dp + y * dst->bytes_per_line);
for (x = 0; x < width; x++) {
*yld = ALPHALEVEL24(*yls, lv);
yls++; yld++;
}
}
break;
}
}
}
-22
View File
@@ -1,22 +0,0 @@
// 8bit surface (or data列)から surface の alpha map へコピー
#include <string.h>
#include "portab.h"
#include "surface.h"
#include "ngraph.h"
#include "ags.h"
void gr_draw_amap(surface_t *dst, int dx, int dy, uint8_t *src, int width, int height, int scanline) {
int y;
uint8_t *sp, *dp;
sp = src;
dp = GETOFFSET_ALPHA(dst, dx, dy);
for (y = 0; y < height; y++) {
memcpy(dp, sp, width);
sp += scanline;
dp += dst->width;
}
}
-56
View File
@@ -1,56 +0,0 @@
// color expansion and blending
// 8bppのモノクロをcolでブレンド
#include "portab.h"
#include "surface.h"
#include "ngraph.h"
#include "ags.h"
void gr_expandcolor_blend(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int sw, int sh, int r, int g, int b) {
uint8_t *sp, *dp;
int x, y;
int col;
if (!gr_clip(src, &sx, &sy, &sw, &sh, dst, &dx, &dy)) {
return;
}
sp = GETOFFSET_PIXEL(src, sx, sy);
dp = GETOFFSET_PIXEL(dst, dx, dy);
switch(dst->depth) {
case 16:
col = PIX16(r, g, b);
{
uint16_t *yd;
uint8_t *ys;
for (y = 0; y < sh; y++) {
ys = (uint8_t *)(sp + y * src->bytes_per_line);
yd = (uint16_t *)(dp + y * dst->bytes_per_line);
for (x = 0; x < sw; x++) {
if (*ys) {
*yd = ALPHABLEND16(col, *yd, (uint8_t)*ys);
}
ys++; yd++;
}
}
}
break;
case 32:
case 24: {
uint32_t *yd;
uint8_t *ys;
col = PIX24(r, g, b);
for (y = 0; y < sh; y++) {
ys = (uint8_t *)(sp + y * src->bytes_per_line);
yd = (uint32_t *)(dp + y * dst->bytes_per_line);
for (x = 0; x < sw; x++) {
if (*ys) {
*yd = ALPHABLEND24(col, *yd, (uint8_t)*ys);
}
ys++; yd++;
}
}
break;
}}
}
-52
View File
@@ -1,52 +0,0 @@
// fill rectangle
#include <string.h>
#include "portab.h"
#include "surface.h"
#include "ngraph.h"
#include "ags.h"
void gr_fill(surface_t *dst, int dx, int dy, int dw, int dh, int r, int g, int b) {
uint8_t *dp, *dp_;
int x, y;
if (!gr_clip_xywh(dst, &dx, &dy, &dw, &dh)) {
return;
}
dp = dp_ = GETOFFSET_PIXEL(dst, dx, dy);
switch(dst->depth) {
case 8:
memset(dp, r, dw);
break;
case 16:
{
uint16_t pic16 = PIX16(r, g, b);
for (x = 0; x < dw; x++) {
*((uint16_t *)dp + x) = pic16;
}
break;
}
case 24:
case 32:
{
uint32_t pic24 = PIX24(r, g, b);
for (x = 0; x < dw; x++) {
*((uint32_t *)dp + x) = pic24;
}
break;
}
}
dp += dst->bytes_per_line;
for (y = 1; y < dh; y++) {
memcpy(dp, dp_, dw * dst->bytes_per_pixel);
dp += dst->bytes_per_line;
}
}
-51
View File
@@ -1,51 +0,0 @@
// 指定の色(rgb)をブレンド率(lv)を指定して矩形塗りつぶし
#include "config.h"
#include "portab.h"
#include "surface.h"
#include "ngraph.h"
#include "ags.h"
void gr_fill_alpha_color(surface_t *dst, int dx, int dy, int dw, int dh, int r, int g, int b, int lv) {
int x, y;
uint8_t *dp;
if (!gr_clip_xywh(dst, &dx, &dy, &dw, &dh)) {
return;
}
dp = GETOFFSET_PIXEL(dst, dx, dy);
switch(dst->depth) {
case 16:
{
uint16_t pic16 = PIX16(r, g, b);
uint16_t *yls;
for (y = 0; y < dh; y++) {
yls = (uint16_t *)(dp + y * dst->bytes_per_line);
for (x = 0; x < dw; x++) {
*yls = ALPHABLEND16(pic16, *yls, lv);
yls++;
}
}
}
break;
case 24:
case 32:
{
uint32_t pic24 = PIX24(r, g, b);
uint32_t *yls;
for (y = 0; y < dh; y++) {
yls = (uint32_t *)(dp + y * dst->bytes_per_line);
for (x = 0; x < dw; x++) {
*yls = ALPHABLEND24(pic24, *yls, lv);
yls++;
}
}
break;
}
}
}
-94
View File
@@ -1,94 +0,0 @@
// draw rectangle
#include "portab.h"
#include "surface.h"
#include "ngraph.h"
#include "ags.h"
void gr_drawrect(surface_t *dst, int x, int y, int w, int h, int r, int g, int b) {
uint8_t *dp;
int i;
int col = 0;
if (!gr_clip_xywh(dst, &x, &y, &w, &h)) {
return;
}
dp = GETOFFSET_PIXEL(dst, x, y);
switch(dst->depth) {
case 8:
col = r; break;
case 16:
col = PIX16(r, g, b); break;
case 24:
case 32:
col = PIX24(r, g, b); break;
}
switch(dst->depth) {
case 8:
/* top */
for (i = 0; i < w; i++) {
*((uint8_t *)dp + i) = col;
}
/* side */
h-=2;
for (i = 0; i < h; i++) {
dp += dst->bytes_per_line;
*((uint8_t *)dp) = col;
*((uint8_t *)dp + w - 1) = col;
}
/* bottom */
dp += dst->bytes_per_line;
for (i = 0; i < w; i++) {
*((uint8_t *)dp + i) = col;
}
break;
case 16:
/* top */
for (i = 0; i < w; i++) {
*((uint16_t *)dp + i) = col;
}
/* side */
h-=2;
for (i = 0; i < h; i++) {
dp += dst->bytes_per_line;
*((uint16_t *)dp) = col;
*((uint16_t *)dp + w - 1) = col;
}
/* bottom */
dp += dst->bytes_per_line;
for (i = 0; i < w; i++) {
*((uint16_t *)dp + i) = col;
}
break;
case 24:
case 32:
/* top */
for (i = 0; i < w; i++) {
*((uint32_t *)dp + i) = col;
}
/* side */
h-=2;
for (i = 0; i < h; i++) {
dp += dst->bytes_per_line;
*((uint32_t *)dp) = col;
*((uint32_t *)dp + w - 1) = col;
}
/* bottom */
dp += dst->bytes_per_line;
for (i = 0; i < w; i++) {
*((uint32_t *)dp + i) = col;
}
break;
}
}
-41
View File
@@ -1,41 +0,0 @@
// alpha map の飽和加算
#include <stdio.h>
#include "portab.h"
#include "system.h"
#include "surface.h"
#include "ngraph.h"
#include "ags.h"
void gr_saturadd_alpha_map(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int sw, int sh) {
uint8_t *sp, *dp;
int x, y;
if (!gr_clip(src, &sx, &sy, &sw, &sh, dst, &dx, &dy)) {
return;
}
if (src->alpha == NULL) {
WARNING("src alpha NULL");
return;
}
if (dst->alpha == NULL) {
WARNING("dst alpha NULL");
return;
}
sp = GETOFFSET_ALPHA(src, sx, sy);
dp = GETOFFSET_ALPHA(dst, dx, dy);
for (y = 0; y < sh; y++) {
uint8_t *yls = sp + y * src->width;
uint8_t *yld = dp + y * dst->width;
for (x = 0; x < sw; x++) {
int s = *yls, d = *yld;
*yld = (uint8_t)(min(255, (s + d)));
yls++; yld++;
}
}
}
-88
View File
@@ -1,88 +0,0 @@
// 拡大・縮小
#include <stdlib.h>
#include <string.h>
#include "portab.h"
#include "surface.h"
#include "ngraph.h"
#include "ags.h"
void gr_copy_stretch(surface_t *dst, int dx, int dy, int dw, int dh, surface_t *src, int sx, int sy, int sw, int sh) {
float a1, a2, xd, yd;
int *row, *col;
int x, y;
uint8_t *sp, *dp;
if (!gr_clip_xywh(dst, &dx, &dy, &dw, &dh)) return;
if (!gr_clip_xywh(src, &sx, &sy, &sw, &sh)) return;
sp = GETOFFSET_PIXEL(src, sx, sy);
dp = GETOFFSET_PIXEL(dst, dx, dy);
a1 = (float)sw / (float)dw;
a2 = (float)sh / (float)dh;
// src width と dst width が同じときに問題があるので+1
row = calloc(dw+1, sizeof(int));
// 1おおきくして初期化しないと col[dw-1]とcol[dw]が同じになる
// 可能性がある。
col = calloc(dh+1, sizeof(int));
for (yd = 0.0, y = 0; y < dh; y++) {
col[y] = yd; yd += a2;
}
for (xd = 0.0, x = 0; x < dw; x++) {
row[x] = xd; xd += a1;
}
switch(dst->depth) {
case 16:
{
uint16_t *yls, *yld;
uint8_t *_yls, *_yld;
for (y = 0; y < dh; y++) {
yls = (uint16_t *)(sp + *(y + col) * src->bytes_per_line);
yld = (uint16_t *)(dp + y * dst->bytes_per_line);
for (x = 0; x < dw; x++) {
*(yld + x) = *(yls + *(row + x));
}
_yld = (uint8_t *)yld;
while (y < dh - 1 && *(col + y) == *(col + y + 1)) {
_yls = _yld;
_yld += dst->bytes_per_line;
memcpy(_yld, _yls, dw * 2);
y++;
}
}
break;
}
case 24:
case 32:
{
uint32_t *yls, *yld;
uint8_t *_yls, *_yld;
for (y = 0; y < dh; y++) {
yls = (uint32_t *)(sp + *(y + col) * src->bytes_per_line);
yld = (uint32_t *)(dp + y * dst->bytes_per_line);
for (x = 0; x < dw; x++) {
*(yld + x) = *(yls+ *(row + x));
}
_yld = (uint8_t *)yld;
while (y < dh - 1 && *(col + y) == *(col + y + 1)) {
_yls = _yld;
_yld += dst->bytes_per_line;
memcpy(_yld, _yls, dw * 4);
y++;
}
}
break;
}
}
free(row);
free(col);
}
-102
View File
@@ -1,102 +0,0 @@
// dst の上に src をalphamapを参照しつつ、ブレンド率 lv でブレンド
// したものを write へ書き出し
#include "config.h"
#include "portab.h"
#include "surface.h"
#include "ngraph.h"
#include "ags.h"
void gre_BlendUseAMap(surface_t *write, int wx, int wy, surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int width, int height, surface_t *alpha, int ax, int ay, int lv) {
uint8_t *sp, *dp, *wp, *ap;
int x, y;
wp = GETOFFSET_PIXEL(write, wx, wy);
sp = GETOFFSET_PIXEL(src, sx, sy);
dp = GETOFFSET_PIXEL(dst, dx, dy);
ap = GETOFFSET_ALPHA(alpha, ax, ay);
if (lv == 255) {
switch(dst->depth) {
case 16:
{
uint16_t *yls, *yld, *ylw;
uint8_t *yla;
for (y = 0; y < height; y++) {
yls = (uint16_t *)(sp + y * src->bytes_per_line);
yld = (uint16_t *)(dp + y * dst->bytes_per_line);
ylw = (uint16_t *)(wp + y * write->bytes_per_line);
yla = (uint8_t *)(ap + y * alpha->width);
for (x = 0; x < width; x++) {
*ylw = ALPHABLEND16(*yls, *yld, *yla);
yls++; yld++; ylw++; yla++;
}
}
}
break;
case 24:
case 32:
{
uint32_t *yls, *yld, *ylw;
uint8_t *yla;
for (y = 0; y < height; y++) {
yls = (uint32_t *)(sp + y * src->bytes_per_line);
yld = (uint32_t *)(dp + y * dst->bytes_per_line);
ylw = (uint32_t *)(wp + y * write->bytes_per_line);
yla = (uint8_t *)(ap + y * alpha->width);
for (x = 0; x < width; x++) {
*ylw = ALPHABLEND24(*yls, *yld, *yla);
yls++; yld++; ylw++; yla++;
}
}
break;
}
}
} else {
switch(dst->depth) {
case 16:
{
uint16_t *yls, *yld, *ylw;
uint8_t *yla;
for (y = 0; y < height; y++) {
yls = (uint16_t *)(sp + y * src->bytes_per_line);
yld = (uint16_t *)(dp + y * dst->bytes_per_line);
ylw = (uint16_t *)(wp + y * write->bytes_per_line);
yla = (uint8_t *)(ap + y * alpha->width);
for (x = 0; x < width; x++) {
*ylw = ALPHABLEND16(*yls, *yld, (*yla * lv) / 255);
yls++; yld++; ylw++; yla++;
}
}
}
break;
case 24:
case 32:
{
uint32_t *yls, *yld, *ylw;
uint8_t *yla;
for (y = 0; y < height; y++) {
yls = (uint32_t *)(sp + y * src->bytes_per_line);
yld = (uint32_t *)(dp + y * dst->bytes_per_line);
ylw = (uint32_t *)(wp + y * write->bytes_per_line);
yla = (uint8_t *)(ap + y * alpha->width);
for (x = 0; x < width; x++) {
*ylw = ALPHABLEND24(*yls, *yld, (*yla * lv) / 255);
yls++; yld++; ylw++; yla++;
}
}
break;
}
}
}
}
-77
View File
@@ -1,77 +0,0 @@
#ifndef __NGRAPH_H__
#define __NGRAPH_H__
#include "portab.h"
#include "nact.h"
#include "ags.h"
#include "surface.h"
#define sf0 nact->ags.dib
// DLL 用 graphic 関連関数
/* in graph.c */
bool gr_clip(surface_t *ss, int *sx, int *sy, int *sw, int *sh, surface_t *ds, int *dx, int *dy);
bool gr_clip_xywh(surface_t *ss, int *sx, int *sy, int *sw, int *sh);
/* in graph_expandcolor_blend.c */
// 8bppのモノクロをcolでブレンド
void gr_expandcolor_blend(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int sw, int sh, int r, int g, int b);
/* in graph_fillrect.c */
void gr_fill(surface_t *dst, int dx, int dy, int dw, int dh, int r, int g, int b);
/* in graph_fillrect_amap.c */
void gr_fill_alpha_map(surface_t *dst, int dx, int dy, int dw, int dh, int lv);
/* in graph_fillrect_acolor.c */
void gr_fill_alpha_color(surface_t *dst, int dx, int dy, int dw, int dh, int r, int g, int b, int lv);
/* in graph_rect.c */
// 矩形枠描画
void gr_drawrect(surface_t *dst, int x, int y, int w, int h, int r, int g, int b);
/* in graph_copy.c */
void gr_copy(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int sw, int sh);
/* in graph_copy_bright.c */
void gr_copy_bright(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int width, int height, int lv);
/* in graph_copy_amap.c */
void gr_copy_alpha_map(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int sw, int sh);
/* in graph_blend_amap.c */
void gr_blend_alpha_map(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int sw, int sh);
/* in graph_saturadd_amap.c */
// alpha map の飽和加算
void gr_saturadd_alpha_map(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int sw, int sh);
/* in graph_draw_amap.c */
void gr_draw_amap(surface_t *dst, int dx, int dy, uint8_t *src, int width, int height, int scanline);
// /* in graph_bright_dst_only.c */
#define gr_bright_dst_only(dst,dx,dy,w,h,lv) gr_copy_bright(dst,dx,dy,dst,dx,dy,w,h,lv)
// void gr_bright_dst_only(surface_t *dst, int dx, int dy, int w, int h, int lv);
/* in gre_blend_useamap.c */
void gre_BlendUseAMap(surface_t *write, int wx, int wy, surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int width, int height, surface_t *alpha, int ax, int ay, int lv);
/* in graph_stretch.c */
void gr_copy_stretch(surface_t *dst, int dx, int dy, int dw, int dh, surface_t *src, int sx, int sy, int sw, int sh);
/* in graph_cg.c */
void gr_drawimage24(surface_t *ds, cgdata *cg, int x, int y);
void gr_drawimage16(surface_t *ds, cgdata *cg, int x, int y);
/* defined in cg.c */
surface_t *sf_getcg(void *buf, size_t size);
surface_t *sf_loadcg_no(int no);
#endif /* __GRAPH_H__ */
-186
View File
@@ -1,186 +0,0 @@
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "portab.h"
#include "surface.h"
#include "system.h"
static surface_t *create(int width, int height, int depth, bool has_pixel, bool has_alpha) {
surface_t *s = calloc(1, sizeof(surface_t));
s->width = width;
s->height = height;
s->bytes_per_line = width;
s->bytes_per_pixel = 1;
s->depth = depth;
if (has_pixel) {
switch (s->depth) {
case 8:
s->pixel = calloc(width * (height +1), sizeof(uint8_t));
s->bytes_per_line = width;
s->bytes_per_pixel = 1;
break;
case 16:
s->pixel = calloc(width * (height +1) * 2, sizeof(uint8_t));
s->bytes_per_line = width * 2;
s->bytes_per_pixel = 2;
break;
case 24:
case 32:
s->pixel = calloc(width * (height +1) * 4, sizeof(uint8_t));
s->bytes_per_line = width * 4;
s->bytes_per_pixel = 4;
break;
default:
WARNING("depth %d is not supported", s->depth);
}
}
if (has_alpha) {
s->alpha = calloc(width * (height +1), sizeof(uint8_t));
}
return s;
}
/**
* surfaceの生成 (pixel + alpha)
* @param width: surfaceの幅
* @param height: surfaceの高さ
* @param depth: surfaceのpixelのBPP (8|16|24|32), alphaは8固定
* @return 生成した surface オブジェクト
*/
surface_t *sf_create_surface(int width, int height, int depth) {
return create(width, height, depth, true, true);
}
/**
* surfaceの生成 (alphaのみ)
* @param width: surfaceの幅
* @param height: surfaceの高さ
* @return 生成した surface オブジェクト
*/
surface_t *sf_create_alpha(int width, int height) {
return create(width, height, 8, false, true);
}
/**
* surfaceの生成 (pixelのみ)
* @param width: surfaceの幅
* @param height: surfaceの高さ
* @param depth: surfaceのBPP(8|16|24|32)
* @return 生成した surface オブジェクト
*/
surface_t *sf_create_pixel(int width, int height, int depth) {
return create(width, height, depth, true, false);
}
/**
* surfaceオブジェクトの開放
* @param s: 開放するオブジェクト
* @return: なし
*/
void sf_free(surface_t *s) {
if (s == NULL) return;
if (s->pixel) free(s->pixel);
if (s->alpha) free(s->alpha);
free(s);
}
/**
* surface の複製を作成(dupulicate)
* @param in: 複製もと
* @return : 複製したsurface
*/
surface_t *sf_dup(surface_t *in) {
surface_t *sf;
int len;
if (in == NULL) return NULL;
sf = malloc(sizeof(surface_t));
memcpy(sf, in, sizeof(surface_t));
if (in->pixel) {
len = sf->bytes_per_line * sf->height;
sf->pixel = malloc(sizeof(uint8_t) * (len + sf->bytes_per_line));
memcpy(sf->pixel, in->pixel, len);
}
if (in->alpha) {
len = sf->width * sf->height;
sf->alpha = malloc(sizeof(uint8_t) * (len + sf->width));
memcpy(sf->alpha, in->alpha, len);
}
return sf;
}
/**
* surface全体のコピー
* @param dst: コピー先 surface
* @param src: コピー元 surface
* @return なし
*/
void sf_copyall(surface_t *dst, surface_t *src) {
int len;
if (src == NULL || dst == NULL) return;
if (src->width != dst->width) return;
if (src->height != dst->height) return;
if (src->bytes_per_pixel != dst->bytes_per_pixel) return;
if (src->alpha && dst->alpha) {
len = src->width * src->height;
memcpy(dst->alpha, src->alpha, len);
}
if (src->pixel && dst->pixel) {
len = src->bytes_per_line * src->height;
memcpy(dst->pixel, src->pixel, len);
}
}
/**
* surface の複製
* @param in: 複製もと
* @param copypixel: pixelをコピーするか
* @param copyalpha: alpha pixel をコピーするか
* @return: 複製した surface
*/
surface_t *sf_dup2(surface_t *in, bool copypixel, bool copyalpha) {
surface_t *sf;
int len;
if (in == NULL) return NULL;
sf = malloc(sizeof(surface_t));
memcpy(sf, in, sizeof(surface_t));
if (in->pixel) {
len = sf->bytes_per_line * sf->height;
sf->pixel = malloc(sizeof(uint8_t) * (len + sf->bytes_per_line));
if (copypixel) {
memcpy(sf->pixel, in->pixel, len);
}
}
if (in->alpha) {
len = sf->width * sf->height;
sf->alpha = malloc(sizeof(uint8_t) * (len + sf->width));
if (copyalpha) {
memcpy(sf->alpha, in->alpha, len);
}
}
return sf;
}
-18
View File
@@ -1,18 +0,0 @@
#ifndef __SURFACE_H__
#define __SURFACE_H__
#include "portab.h"
#include "ags.h"
#define surface_t agsurface_t
extern surface_t *sf_create_surface(int width, int height, int depth);
extern surface_t *sf_create_alpha(int width, int height);
extern surface_t *sf_create_pixel(int width, int height, int depth);
extern void sf_free(surface_t *s);
extern surface_t *sf_dup(surface_t *in);
extern surface_t *sf_dup2(surface_t *in, bool copypixel, bool copyalpha);
extern void sf_copyall(surface_t *dst, surface_t *src);
#endif /* __SURFACE_H__ */

Some files were not shown because too many files have changed in this diff Show More