mirror of
https://github.com/LHY0125/Gobang-Game.git
synced 2026-05-10 02:19:46 +08:00
Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f897536a45 | |||
| 249dc2ab4b | |||
| 88f12bcfea | |||
| 0c9cfba81b | |||
| dd2b6fd903 | |||
| 0baab8bec6 | |||
| d796065bb9 | |||
| 1332d14347 | |||
| ec63b6d97c | |||
| 8bddf6bb37 | |||
| a0944f8e16 | |||
| 17d7079c41 | |||
| 1abde99a68 | |||
| 205e943bcb | |||
| ae0629ef6e | |||
| 2121831478 | |||
| a11ddeb8d1 | |||
| 39d84f38cf | |||
| 198a8a2943 | |||
| 0e53b09d9b | |||
| 1d8e2e25cf | |||
| 6d4de737c4 | |||
| b413f7254a | |||
| cb81105809 | |||
| fbe4f5273c | |||
| 59c816767b | |||
| 504868c739 | |||
| 6bd2289722 | |||
| 7ec7fa23de | |||
| 8dfab71559 | |||
| e08e26f9cf | |||
| 814a46ebfd | |||
| bb05390e1d | |||
| 6d3749bf8d |
+40
@@ -0,0 +1,40 @@
|
||||
# 编译生成的可执行文件
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# IDE配置文件
|
||||
.idea/
|
||||
.vscode/
|
||||
.vs/
|
||||
|
||||
# Trae AI配置文件
|
||||
.trae/
|
||||
|
||||
# 临时文件
|
||||
*.tmp
|
||||
*.temp
|
||||
*.log
|
||||
|
||||
# 系统文件
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# 备份文件
|
||||
*.bak
|
||||
*.backup
|
||||
|
||||
# 调试文件
|
||||
*.pdb
|
||||
*.ilk
|
||||
|
||||
# 对象文件
|
||||
*.obj
|
||||
|
||||
# 打包文件
|
||||
dist/
|
||||
|
||||
# 编译生成的对象文件
|
||||
obj/
|
||||
|
||||
# 临时游戏存档
|
||||
records/
|
||||
@@ -0,0 +1,102 @@
|
||||
# 五子棋游戏 Makefile
|
||||
# 支持编译GUI版本 (IUP)
|
||||
|
||||
# 编译器设置
|
||||
CC = gcc
|
||||
# 显式指定 Shell 为 PowerShell
|
||||
SHELL = D:/PowerShell/PowerShell-7.5.4/PowerShell.exe
|
||||
.SHELLFLAGS = -NoProfile -Command
|
||||
|
||||
CFLAGS = -Wall -Wextra -std=c17 -O2 -Iinclude -finput-charset=UTF-8 -fexec-charset=UTF-8
|
||||
# ENet 包含路径
|
||||
ENET_INC = -Ilibs/enet/include
|
||||
CFLAGS += $(ENET_INC)
|
||||
|
||||
LDFLAGS = -lws2_32 -lwinmm
|
||||
|
||||
|
||||
# IUP路径设置
|
||||
IUP_PATH = libs/iup-3.31_Win64_dllw6_lib
|
||||
IUP_INCLUDE = "-I$(IUP_PATH)/include"
|
||||
# IUP链接库: iup, gdi32, comdlg32, comctl32, uuid, ole32
|
||||
IUP_LIBS = "-L$(IUP_PATH)" -liup -lgdi32 -lcomdlg32 -lcomctl32 -luuid -lole32
|
||||
|
||||
# 目录设置
|
||||
SRC_DIR = src
|
||||
OBJ_DIR = obj
|
||||
BIN_DIR = bin
|
||||
|
||||
# 源文件
|
||||
COMMON_SOURCES = $(SRC_DIR)/gobang.c $(SRC_DIR)/ai.c $(SRC_DIR)/config.c \
|
||||
$(SRC_DIR)/globals.c \
|
||||
$(SRC_DIR)/network.c $(SRC_DIR)/record.c \
|
||||
$(SRC_DIR)/gui_core.c $(SRC_DIR)/gui_draw.c \
|
||||
$(SRC_DIR)/gui_game.c $(SRC_DIR)/gui_replay.c \
|
||||
$(SRC_DIR)/gui_menu.c
|
||||
|
||||
# ENet 源文件
|
||||
ENET_SOURCES = libs/enet/callbacks.c libs/enet/compress.c libs/enet/host.c \
|
||||
libs/enet/list.c libs/enet/packet.c libs/enet/peer.c \
|
||||
libs/enet/protocol.c libs/enet/win32.c
|
||||
|
||||
# 目标文件 (src/xxx.c -> obj/xxx.o)
|
||||
COMMON_OBJECTS = $(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR)/%.o,$(COMMON_SOURCES))
|
||||
ENET_OBJECTS = $(patsubst libs/enet/%.c,$(OBJ_DIR)/enet_%.o,$(ENET_SOURCES))
|
||||
|
||||
# 可执行文件
|
||||
GUI_TARGET = $(BIN_DIR)/gobang_gui.exe
|
||||
|
||||
# 默认目标
|
||||
all: directories $(GUI_TARGET)
|
||||
|
||||
# 创建目录 (PowerShell 语法)
|
||||
directories:
|
||||
if (!(Test-Path "$(OBJ_DIR)")) { New-Item -ItemType Directory -Path "$(OBJ_DIR)" | Out-Null }
|
||||
if (!(Test-Path "$(BIN_DIR)")) { New-Item -ItemType Directory -Path "$(BIN_DIR)" | Out-Null }
|
||||
|
||||
# GUI版本
|
||||
$(GUI_TARGET): $(COMMON_OBJECTS) $(ENET_OBJECTS) $(OBJ_DIR)/main.o
|
||||
$(CC) $(CFLAGS) $(IUP_INCLUDE) -o $@ $^ $(IUP_LIBS) $(LDFLAGS)
|
||||
Copy-Item -Path "$(subst /,\,$(IUP_PATH))\iup.dll" -Destination "$(BIN_DIR)" -Force
|
||||
|
||||
# 通用目标文件编译规则
|
||||
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
|
||||
$(CC) $(CFLAGS) $(IUP_INCLUDE) -c -o $@ $<
|
||||
|
||||
# 编译 ENet 源文件
|
||||
$(OBJ_DIR)/enet_%.o: libs/enet/%.c | directories
|
||||
$(CC) $(CFLAGS) $(ENET_INC) -c -o $@ $<
|
||||
|
||||
# 编译 main.c
|
||||
$(OBJ_DIR)/main.o: $(SRC_DIR)/main.c
|
||||
$(CC) $(CFLAGS) $(IUP_INCLUDE) -c -o $@ $<
|
||||
|
||||
# 清理规则 (PowerShell 语法)
|
||||
clean:
|
||||
if (Test-Path "$(OBJ_DIR)") { Remove-Item -Path "$(OBJ_DIR)" -Recurse -Force }
|
||||
if (Test-Path "$(BIN_DIR)") { Remove-Item -Path "$(BIN_DIR)" -Recurse -Force }
|
||||
|
||||
# 编译GUI版本
|
||||
gui: directories $(GUI_TARGET)
|
||||
|
||||
# 安装规则(可选)
|
||||
install: all
|
||||
Write-Host "Installing executables..."
|
||||
Copy-Item -Path "$(GUI_TARGET)" -Destination "C:\Program Files\Gobang\" -Force
|
||||
|
||||
# 运行GUI版本
|
||||
run-gui: $(GUI_TARGET)
|
||||
& ".\$(GUI_TARGET)"
|
||||
|
||||
# 帮助信息
|
||||
help:
|
||||
@echo Available targets:
|
||||
@echo all - Build GUI version
|
||||
@echo gui - Build GUI version
|
||||
@echo clean - Remove all object files and executables
|
||||
@echo run-gui - Build and run GUI version
|
||||
@echo install - Install executables to system directory
|
||||
@echo help - Show this help message
|
||||
|
||||
# 声明伪目标
|
||||
.PHONY: all clean gui install run-gui help directories
|
||||
@@ -1,54 +1,157 @@
|
||||
# 五子棋人机对战AI
|
||||
|
||||
## 项目简介
|
||||
基于C语言实现的五子棋人机对战系统,采用α-β剪枝优化的极小极大算法,支持自定义棋盘大小和游戏复盘功能。
|
||||
|
||||
## 功能特性
|
||||
- 🎮 人机对战模式
|
||||
- ⚙️ 可调棋盘尺寸(5x5到25x25)
|
||||
- 🧠 智能AI决策(1-5级难度)
|
||||
- 🔍 完整游戏复盘功能
|
||||
- 📊 清晰的终端界面显示
|
||||
|
||||
## 快速开始
|
||||
### 编译程序
|
||||
```bash
|
||||
gcc 五子棋.c gobang.c -o output/五子棋.exe
|
||||
```
|
||||
|
||||
### 运行游戏
|
||||
```bash
|
||||
.\output\五子棋.exe
|
||||
```
|
||||
|
||||
## 游戏玩法
|
||||
1. 启动后设置棋盘大小(默认15x15)
|
||||
2. 选择AI难度级别(1-5)
|
||||
3. 输入坐标进行游戏(格式:行 列)
|
||||
4. 游戏结束可查看完整复盘
|
||||
|
||||
## 技术实现
|
||||
### 核心算法
|
||||
- α-β剪枝优化的极小极大算法
|
||||
- 3层搜索深度(可调)
|
||||
- 威胁检测优先机制
|
||||
|
||||
### 评估系统
|
||||
- 活四/冲四/活三等棋型识别
|
||||
- 位置权重评估(中心优先)
|
||||
- 双向延伸检测
|
||||
|
||||
## 开发说明
|
||||
### 代码结构
|
||||
- `五子棋.c` - 主程序(游戏流程控制)
|
||||
- `gobang.c` - 核心算法实现
|
||||
- `gobang.h` - 公共定义和接口
|
||||
|
||||
### 关键函数
|
||||
- `ai_move()` - AI决策入口
|
||||
- `evaluate_pos()` - 位置评估
|
||||
- `dfs()` - α-β剪枝搜索
|
||||
- `check_win()` - 胜负判断
|
||||
|
||||
## 许可证
|
||||
自由使用,请注明原作者。
|
||||
# C语言五子棋系统
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
> 🎯 **最新版本 v9.0** - 全面集成 ENet 网络联机功能,重构 GUI 代码架构,纯图形化交互体验。
|
||||
|
||||
## 📋 大版本更新
|
||||
|
||||
### v9.0 (2026-03-17) - 局域网联机与 GUI 架构重构
|
||||
|
||||
- 🌐 **局域网对战** - 引入 ENet 库,支持稳定、无粘包的局域网多人对战(创建房间/加入房间)。
|
||||
- 🎨 **GUI 深度重构** - 拆分臃肿的 GUI 代码,模块化为 `gui_core`, `gui_game`, `gui_menu`, `gui_draw`, `gui_replay`,大幅提升可维护性。
|
||||
- 📦 **精简安装包** - 优化 Inno Setup 打包脚本,实现极简核心依赖打包。
|
||||
- � **全面摒弃控制台** - 专注于基于 IUP 的原生图形化交互体验。
|
||||
|
||||
---
|
||||
|
||||
## 目录
|
||||
|
||||
- [C语言五子棋系统](#c语言五子棋系统)
|
||||
- [📋 大版本更新](#-大版本更新)
|
||||
- [v9.0 (2026-03-17) - 局域网联机与 GUI 架构重构](#v90-2026-03-17---局域网联机与-gui-架构重构)
|
||||
- [目录](#目录)
|
||||
- [项目简介](#项目简介)
|
||||
- [功能特性](#功能特性)
|
||||
- [🎮 游戏模式](#-游戏模式)
|
||||
- [⚙️ 核心功能](#️-核心功能)
|
||||
- [快速开始](#快速开始)
|
||||
- [编译项目](#编译项目)
|
||||
- [打包安装程序](#打包安装程序)
|
||||
- [游戏玩法](#游戏玩法)
|
||||
- [技术架构](#技术架构)
|
||||
- [AI 算法](#ai-算法)
|
||||
- [网络通信](#网络通信)
|
||||
- [图形界面](#图形界面)
|
||||
- [项目结构](#项目结构)
|
||||
- [许可证](#许可证)
|
||||
|
||||
---
|
||||
|
||||
## 项目简介
|
||||
|
||||
这是一个使用纯 C 语言编写的现代化五子棋系统。采用轻量级的 IUP 库构建原生风格的图形化用户界面。系统不仅支持基于 Minimax 算法(带 Alpha-Beta 剪枝)的高级人机对战,还完美支持基于 ENet 的局域网多人实时联机对弈。
|
||||
|
||||
## 功能特性
|
||||
|
||||
### 🎮 游戏模式
|
||||
|
||||
- **人机对战 (PvE)** - 挑战 1-5 级难度的智能 AI。
|
||||
- **局域网联机 (Network)** - 建立主机或作为客机加入,与朋友在局域网内实时对战。
|
||||
- **复盘模式 (Replay)** - 载入自动保存的对局记录(CSV),逐步回放并分析对局。
|
||||
|
||||
### ⚙️ 核心功能
|
||||
|
||||
- **实时对局控制** - 支持悔棋(PvE)、断线重连检测、胜负判定。
|
||||
- **自动游戏记录** - 每局游戏结束后自动保存至 `bin/records/` 目录。
|
||||
- **模块化构建** - 提供高度配置化的 Makefile,一键源码编译包含 ENet 和主程序的二进制文件。
|
||||
|
||||
---
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 编译项目
|
||||
|
||||
项目使用 Makefile 进行构建,依赖 MinGW-w64 工具链。
|
||||
在项目根目录下打开 PowerShell 或 CMD,运行:
|
||||
|
||||
```bash
|
||||
# 清理旧文件
|
||||
mingw32-make clean
|
||||
|
||||
# 编译生成 GUI 可执行文件
|
||||
mingw32-make gui
|
||||
```
|
||||
|
||||
生成的可执行文件 `gobang_gui.exe` 和所需的动态链接库 `iup.dll` 会输出到 `bin/` 目录下。
|
||||
|
||||
**运行游戏:**
|
||||
|
||||
```bash
|
||||
.\bin\gobang_gui.exe
|
||||
```
|
||||
|
||||
### 打包安装程序
|
||||
|
||||
如果你需要将游戏打包成 Windows 安装程序,项目提供了 Inno Setup 脚本。
|
||||
确保你已安装 [Inno Setup 6](https://jrsoftware.org/isinfo.php),然后运行:
|
||||
|
||||
```powershell
|
||||
& "D:\Program Files (x86)\Inno Setup 6\iscc.exe" installer\installer.iss
|
||||
```
|
||||
|
||||
生成的安装包 `Gobang_Inno_Setup.exe` 将存放在 `installer\dist\` 目录下。
|
||||
|
||||
---
|
||||
|
||||
## 游戏玩法
|
||||
|
||||
1. 运行 `gobang_gui.exe` 启动游戏主菜单。
|
||||
2. 选择你要进行的游戏模式:
|
||||
- **人机对战**:直接进入游戏,玩家执黑先行,点击棋盘空白处落子。
|
||||
- **局域网联机**:
|
||||
- **作为房主**:点击“局域网联机” -> “创建房间”,等待好友加入(默认端口8888)。
|
||||
- **作为玩家**:点击“局域网联机” -> 输入房主的 IP 地址和端口 -> “加入房间”。
|
||||
- **复盘模式**:选择历史对局记录,使用“上一步/下一步”按钮进行回放。
|
||||
|
||||
---
|
||||
|
||||
## 技术架构
|
||||
|
||||
### AI 算法
|
||||
|
||||
- **Minimax 博弈树**:遍历所有可能的落子情况。
|
||||
- **Alpha-Beta 剪枝**:极大提升搜索效率,AI 默认思考深度为 3 层。
|
||||
- **启发式评估函数**:基于连五、活四、冲四、活三等经典五子棋棋型进行棋局评分。
|
||||
|
||||
### 网络通信
|
||||
|
||||
- **底层库**:[ENet](http://enet.bespin.org/) (基于 UDP 的可靠网络传输协议)。
|
||||
- **机制**:游戏采用非阻塞轮询机制处理网络事件,完美解决传统 TCP 粘包问题,确保落子坐标、断开连接等指令 100% 可靠送达。
|
||||
|
||||
### 图形界面
|
||||
|
||||
- **底层库**:[IUP](https://www.tecgraf.puc-rio.br/iup/) (轻量级、跨平台的 C 语言原生 GUI 库)。
|
||||
- **机制**:事件驱动架构,通过回调函数响应用户的鼠标点击、按钮触发和窗口切换。
|
||||
|
||||
---
|
||||
|
||||
## 项目结构
|
||||
|
||||
```text
|
||||
Gobang/
|
||||
├── bin/ # 编译输出目录 (包含 exe, dll 和 records)
|
||||
├── include/ # 头文件目录
|
||||
├── libs/ # 第三方库源码及预编译库 (ENet, IUP)
|
||||
├── src/ # 核心源代码
|
||||
│ ├── main.c # 程序入口
|
||||
│ ├── gobang.c # 五子棋核心规则与逻辑
|
||||
│ ├── ai.c # 智能 AI 算法
|
||||
│ ├── network.c # ENet 网络通信封装
|
||||
│ ├── record.c # 棋谱记录与解析
|
||||
│ ├── gui_core.c # GUI 初始化与核心循环
|
||||
│ ├── gui_game.c # 游戏主界面与交互逻辑
|
||||
│ ├── gui_menu.c # 游戏主菜单界面
|
||||
│ ├── gui_draw.c # 棋盘与棋子渲染
|
||||
│ └── gui_replay.c # 复盘模式交互逻辑
|
||||
├── installer/ # Inno Setup 安装包打包脚本及输出
|
||||
├── Makefile # 自动化构建脚本
|
||||
└── README.md # 项目说明文档
|
||||
```
|
||||
|
||||
## 许可证
|
||||
|
||||
本项目采用 [MIT 许可证](https://opensource.org/licenses/MIT)授权。欢迎自由修改和分发!
|
||||
|
||||
Binary file not shown.
BIN
Binary file not shown.
@@ -1,526 +0,0 @@
|
||||
#include "gobang.h"
|
||||
|
||||
// 全局变量定义
|
||||
int BOARD_SIZE = 15; // 实际使用的棋盘尺寸(默认15)
|
||||
int board[MAX_BOARD_SIZE][MAX_BOARD_SIZE] = {0}; // 棋盘状态存储数组(默认棋盘全空为0)
|
||||
const int direction[4][2] = {{1, 0}, {0, 1}, {1, 1}, {1, -1}}; // 四个方向:向下、向右、右下、左下
|
||||
Step steps[MAX_STEPS]; // 存储所有落子步骤的数组
|
||||
int step_count = 0; // 当前步数计数器
|
||||
|
||||
/**
|
||||
* @brief 初始化棋盘为全空状态并重置步数计数器
|
||||
* 清空棋盘数组并将所有位置设为EMPTY,同时将step_count重置为0
|
||||
*/
|
||||
void empty_board()
|
||||
{
|
||||
// 初始化棋盘状态为全空
|
||||
for (int i = 0; i < BOARD_SIZE; i++)
|
||||
{
|
||||
for (int j = 0; j < BOARD_SIZE; j++)
|
||||
{
|
||||
board[i][j] = EMPTY;
|
||||
}
|
||||
}
|
||||
step_count = 0; // 重置步数计数器
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 打印当前棋盘状态
|
||||
* 以可读格式输出棋盘,包括行列号和棋子状态
|
||||
* 玩家棋子显示为'x',AI棋子显示为'○',空位显示为'·'
|
||||
*/
|
||||
void print_board()
|
||||
{
|
||||
// 打印列号(1-BOARD_SIZE显示)
|
||||
printf("\n ");
|
||||
for (int i = 0; i < BOARD_SIZE; i++)
|
||||
{
|
||||
printf("%2d", i + 1);
|
||||
if (i + 1 == 9) // 处理列号9和10+的对齐
|
||||
printf(" ");
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
// 逐行打印棋盘内容
|
||||
for (int i = 0; i < BOARD_SIZE; i++)
|
||||
{
|
||||
printf("%2d ", i + 1); // 打印行号(1-BOARD_SIZE)
|
||||
for (int j = 0; j < BOARD_SIZE; j++)
|
||||
{
|
||||
if (board[i][j] == PLAYER)
|
||||
printf("x "); // 玩家棋子
|
||||
else if (board[i][j] == AI)
|
||||
printf("○ "); // AI棋子(使用○显示)
|
||||
else
|
||||
printf("· "); // 空位
|
||||
}
|
||||
printf("\n"); // 每行结束换行
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 检查指定位置是否有效且为空
|
||||
* @param x 行坐标(0-base)
|
||||
* @param y 列坐标(0-base)
|
||||
* @return true 位置有效且为空
|
||||
* @return false 位置无效或已被占用
|
||||
*/
|
||||
bool have_space(int x, int y)
|
||||
{
|
||||
// 校验坐标是否在范围内且该位置为空
|
||||
return (x >= 0 && x < BOARD_SIZE && y >= 0 && y < BOARD_SIZE && board[x][y] == EMPTY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 执行玩家落子操作
|
||||
* @param x 行坐标(0-base)
|
||||
* @param y 列坐标(0-base)
|
||||
* @return true 落子成功
|
||||
* @return false 落子失败(位置无效)
|
||||
*/
|
||||
bool player_move(int x, int y)
|
||||
{
|
||||
// 位置无效则返回false
|
||||
if (!have_space(x, y))
|
||||
return false;
|
||||
|
||||
// 更新棋盘状态
|
||||
board[x][y] = PLAYER;
|
||||
// 记录落子步骤:玩家标识和坐标
|
||||
steps[step_count++] = (Step){PLAYER, x, y};
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 计算特定方向上连续同色棋子数量
|
||||
* @param x 起始行坐标
|
||||
* @param y 起始列坐标
|
||||
* @param dx 行方向增量(-1,0,1)
|
||||
* @param dy 列方向增量(-1,0,1)
|
||||
* @param player 玩家标识(PLAYER/AI)
|
||||
* @return DirInfo 包含连续棋子数和方向开放状态的结构体
|
||||
* @note 检查正反两个方向,统计连续棋子数并判断端点是否开放
|
||||
*/
|
||||
DirInfo count_specific_direction(int x, int y, int dx, int dy, int player)
|
||||
{
|
||||
DirInfo info;
|
||||
info.continuous_chess = 1; // 起始位置已经有一个棋子
|
||||
info.check_start = false; // 起点方向是否开放
|
||||
info.check_end = false; // 终点方向是否开放
|
||||
|
||||
// 检查正方向(dx, dy)
|
||||
int nx = x + dx, ny = y + dy;
|
||||
while (nx >= 0 && nx < BOARD_SIZE && ny >= 0 && ny < BOARD_SIZE && board[nx][ny] == player)
|
||||
{
|
||||
info.continuous_chess++; // 连续棋子计数增加
|
||||
nx += dx; // 沿当前方向前进
|
||||
ny += dy;
|
||||
}
|
||||
// 判断正方向端点是否开放(遇到空位)
|
||||
if (nx >= 0 && nx < BOARD_SIZE && ny >= 0 && ny < BOARD_SIZE)
|
||||
if (board[nx][ny] == EMPTY)
|
||||
info.check_end = true;
|
||||
|
||||
// 检查反方向(-dx, -dy)
|
||||
nx = x - dx, ny = y - dy;
|
||||
while (nx >= 0 && nx < BOARD_SIZE && ny >= 0 && ny < BOARD_SIZE && board[nx][ny] == player)
|
||||
{
|
||||
info.continuous_chess++; // 连续棋子计数增加
|
||||
nx -= dx; // 沿相反方向前进
|
||||
ny -= dy;
|
||||
}
|
||||
// 判断反方向端点是否开放(遇到空位)
|
||||
if (nx >= 0 && nx < BOARD_SIZE && ny >= 0 && ny < BOARD_SIZE)
|
||||
if (board[nx][ny] == EMPTY)
|
||||
info.check_start = true;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 检查特定位置落子后是否形成五连珠获胜
|
||||
* @param x 行坐标(0-base)
|
||||
* @param y 列坐标(0-base)
|
||||
* @param player 玩家标识(PLAYER/AI)
|
||||
* @return true 在任意方向形成五连珠
|
||||
* @return false 未形成五连珠
|
||||
* @note 检查四个方向(水平、垂直、对角线)是否存在连续5个同色棋子
|
||||
*/
|
||||
bool check_win(int x, int y, int player)
|
||||
{
|
||||
// 检查四个方向是否存在五连珠
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
DirInfo info = count_specific_direction(x, y, direction[i][0], direction[i][1], player);
|
||||
if (info.continuous_chess >= 5) // 连续棋子>=5即获胜
|
||||
return true;
|
||||
}
|
||||
return false; // 四个方向都没有五连珠
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 评估特定位置对当前玩家的战略价值
|
||||
* @param x 行坐标(0-base)
|
||||
* @param y 列坐标(0-base)
|
||||
* @param player 玩家标识(PLAYER/AI)
|
||||
* @return int 综合评估分数(越高表示位置越好)
|
||||
* @note 评分标准:
|
||||
* - 活四:100000 冲四:10000 死四:500
|
||||
* - 活三:5000 眠三:1000 死三:50
|
||||
* - 活二:500 眠二:100 死二:10
|
||||
* - 单子:50(开放)/10(半开放)/1(封闭)
|
||||
* - 中心位置有额外加成
|
||||
*/
|
||||
int evaluate_pos(int x, int y, int player)
|
||||
{
|
||||
// 保存原始值用于还原
|
||||
int original = board[x][y];
|
||||
// 模拟在该位置落子
|
||||
board[x][y] = player;
|
||||
|
||||
int total_score = 0; // 总分
|
||||
int line_scores[4] = {0}; // 四个方向的得分
|
||||
|
||||
// 遍历四个方向进行评估
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int dx = direction[i][0], dy = direction[i][1];
|
||||
// 获取当前方向上的棋型信息
|
||||
DirInfo info = count_specific_direction(x, y, dx, dy, player);
|
||||
|
||||
// 直接形成五连珠为必胜
|
||||
if (info.continuous_chess >= 5)
|
||||
{
|
||||
board[x][y] = original; // 还原棋盘
|
||||
return 1000000; // 返回最大分
|
||||
}
|
||||
|
||||
// 根据连续棋子数评分
|
||||
switch (info.continuous_chess)
|
||||
{
|
||||
case 4: // 四连珠
|
||||
if (info.check_start && info.check_end) // 活四(两端开放)
|
||||
line_scores[i] = 100000;
|
||||
else if (info.check_start || info.check_end) // 冲四(一端开放)
|
||||
line_scores[i] = 10000;
|
||||
else // 死四(两端封闭)
|
||||
line_scores[i] = 500;
|
||||
break;
|
||||
|
||||
case 3: // 三连珠
|
||||
if (info.check_start && info.check_end) // 活三
|
||||
line_scores[i] = 5000;
|
||||
else if (info.check_start || info.check_end) // 眠三
|
||||
line_scores[i] = 1000;
|
||||
else // 死三
|
||||
line_scores[i] = 50;
|
||||
break;
|
||||
|
||||
case 2: // 二连珠
|
||||
if (info.check_start && info.check_end) // 活二
|
||||
line_scores[i] = 500;
|
||||
else if (info.check_start || info.check_end) // 眠二
|
||||
line_scores[i] = 100;
|
||||
else // 死二
|
||||
line_scores[i] = 10;
|
||||
break;
|
||||
|
||||
case 1: // 单子
|
||||
if (info.check_start && info.check_end) // 开放位置
|
||||
line_scores[i] = 50;
|
||||
else if (info.check_start || info.check_end) // 半开放位置
|
||||
line_scores[i] = 10;
|
||||
else // 封闭位置
|
||||
line_scores[i] = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 计算总分(最高方向分+其他方向分加权)
|
||||
int max_score = 0;
|
||||
int sum_score = 0;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (line_scores[i] > max_score)
|
||||
max_score = line_scores[i];
|
||||
sum_score += line_scores[i];
|
||||
}
|
||||
total_score = max_score * 10 + sum_score; // 主方向权重更高
|
||||
|
||||
// 位置奖励:越靠近中心分数越高
|
||||
int center_x = BOARD_SIZE / 2;
|
||||
int center_y = BOARD_SIZE / 2;
|
||||
int distance = abs(x - center_x) + abs(y - center_y); // 曼哈顿距离
|
||||
int position_bonus = 50 * (BOARD_SIZE - distance); // 距离中心越近奖励越高
|
||||
|
||||
board[x][y] = original; // 还原棋盘状态
|
||||
return total_score + position_bonus; // 返回总评估分
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 带α-β剪枝的深度优先搜索(极小极大算法实现)
|
||||
* @param x 当前行坐标
|
||||
* @param y 当前列坐标
|
||||
* @param player 当前玩家
|
||||
* @param depth 剩余搜索深度
|
||||
* @param alpha α值(当前最大值)
|
||||
* @param beta β值(当前最小值)
|
||||
* @param is_maximizing 是否为极大化玩家(AI)
|
||||
* @return int 最佳评估分数
|
||||
* @note 算法流程:
|
||||
* 1. 检查是否获胜或达到搜索深度
|
||||
* 2. 遍历所有可能落子位置
|
||||
* 3. 递归评估每个位置的分数
|
||||
* 4. 根据is_maximizing选择最大/最小值
|
||||
* 5. 使用α-β剪枝优化搜索过程
|
||||
*/
|
||||
int dfs(int x, int y, int player, int depth, int alpha, int beta, bool is_maximizing)
|
||||
{
|
||||
// 检查当前落子是否获胜
|
||||
if (check_win(x, y, player))
|
||||
{
|
||||
return (player == AI) ? 1000000 + depth : -1000000 - depth;
|
||||
}
|
||||
|
||||
// 达到搜索深度或平局
|
||||
if (depth == 0 || step_count >= BOARD_SIZE * BOARD_SIZE)
|
||||
{
|
||||
return evaluate_pos(x, y, AI) - evaluate_pos(x, y, PLAYER);
|
||||
}
|
||||
|
||||
int best_score = is_maximizing ? -1000000 : 1000000;
|
||||
|
||||
// 遍历所有可能落子位置
|
||||
for (int i = 0; i < BOARD_SIZE; i++)
|
||||
{
|
||||
for (int j = 0; j < BOARD_SIZE; j++)
|
||||
{
|
||||
if (board[i][j] != EMPTY)
|
||||
continue;
|
||||
|
||||
// 模拟当前玩家落子
|
||||
board[i][j] = player;
|
||||
step_count++;
|
||||
|
||||
// 递归搜索(切换玩家和搜索深度)
|
||||
int current_score = dfs(i, j, (player == AI) ? PLAYER : AI, depth - 1, alpha, beta, !is_maximizing);
|
||||
|
||||
// 撤销落子
|
||||
board[i][j] = EMPTY;
|
||||
step_count--;
|
||||
|
||||
// 极大值玩家(AI)逻辑
|
||||
if (is_maximizing)
|
||||
{
|
||||
best_score = (current_score > best_score) ? current_score : best_score;
|
||||
alpha = (best_score > alpha) ? best_score : alpha;
|
||||
// α剪枝
|
||||
if (beta <= alpha)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 极小值玩家(人类)逻辑
|
||||
else
|
||||
{
|
||||
best_score = (current_score < best_score) ? current_score : best_score;
|
||||
beta = (best_score < beta) ? best_score : beta;
|
||||
// β剪枝
|
||||
if (beta <= alpha)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((is_maximizing && best_score >= beta) || (!is_maximizing && best_score <= alpha))
|
||||
{
|
||||
break; // 提前退出外层循环
|
||||
}
|
||||
}
|
||||
|
||||
return best_score;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief AI决策主函数,使用评估函数和搜索算法选择最佳落子位置
|
||||
* @note 采用两阶段决策逻辑:
|
||||
* 1. 防御阶段:检查并阻止玩家即将获胜的位置(活四、冲四、活三)
|
||||
* 2. 进攻阶段:若无紧急防御需求,使用DFS评估选择最佳进攻位置
|
||||
* @note 实现细节:
|
||||
* - 优先处理玩家活四、冲四等危险局面
|
||||
* - 步数>10时缩小搜索范围到已有棋子附近2格
|
||||
* - 使用中心位置优先策略
|
||||
*/
|
||||
void ai_move(int depth)
|
||||
{
|
||||
// 1. 首先检查是否需要阻止玩家的四子连棋或三子活棋
|
||||
for (int i = 0; i < BOARD_SIZE; i++)
|
||||
{
|
||||
for (int j = 0; j < BOARD_SIZE; j++)
|
||||
{
|
||||
if (board[i][j] != EMPTY)
|
||||
continue;
|
||||
|
||||
// 模拟玩家在此位置落子
|
||||
board[i][j] = PLAYER;
|
||||
bool need_block = false;
|
||||
|
||||
// 检查四个方向
|
||||
for (int k = 0; k < 4; k++)
|
||||
{
|
||||
DirInfo info = count_specific_direction(i, j, direction[k][0], direction[k][1], PLAYER);
|
||||
|
||||
// 如果玩家能形成四子连棋且至少一端开放
|
||||
if (info.continuous_chess >= 4 && (info.check_start || info.check_end))
|
||||
{
|
||||
need_block = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// 如果玩家能形成三子活棋且两端开放
|
||||
if (info.continuous_chess == 3 && info.check_start && info.check_end)
|
||||
{
|
||||
need_block = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
board[i][j] = EMPTY; // 恢复棋盘
|
||||
|
||||
if (need_block)
|
||||
{
|
||||
// 必须在此位置落子阻止
|
||||
board[i][j] = AI;
|
||||
steps[step_count++] = (Step){AI, i, j};
|
||||
printf("AI落子(%d, %d)\n", i + 1, j + 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 如果没有需要立即阻止的情况,则正常评估
|
||||
int best_score = -1000000;
|
||||
int best_x = -1, best_y = -1;
|
||||
|
||||
// 遍历棋盘所有空位
|
||||
for (int i = 0; i < BOARD_SIZE; i++)
|
||||
{
|
||||
for (int j = 0; j < BOARD_SIZE; j++)
|
||||
{
|
||||
if (board[i][j] != EMPTY)
|
||||
continue;
|
||||
|
||||
// 只考虑已有棋子附近(2格范围内)
|
||||
bool has_nearby_stone = false;
|
||||
for (int di = -2; di <= 2; di++)
|
||||
{
|
||||
for (int dj = -2; dj <= 2; dj++)
|
||||
{
|
||||
int ni = i + di;
|
||||
int nj = j + dj;
|
||||
if (ni >= 0 && ni < BOARD_SIZE &&
|
||||
nj >= 0 && nj < BOARD_SIZE)
|
||||
{
|
||||
if (board[ni][nj] != EMPTY)
|
||||
{
|
||||
has_nearby_stone = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (has_nearby_stone)
|
||||
break;
|
||||
}
|
||||
if (!has_nearby_stone && step_count > 10)
|
||||
continue;
|
||||
|
||||
// 模拟AI落子
|
||||
board[i][j] = AI;
|
||||
int current_score = dfs(i, j, PLAYER, depth, -1000000, 1000000, false);
|
||||
board[i][j] = EMPTY;
|
||||
|
||||
// 更新最佳位置
|
||||
if (current_score > best_score)
|
||||
{
|
||||
best_score = current_score;
|
||||
best_x = i;
|
||||
best_y = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 执行最佳落子
|
||||
if (best_x != -1 && best_y != -1)
|
||||
{
|
||||
board[best_x][best_y] = AI;
|
||||
steps[step_count++] = (Step){AI, best_x, best_y};
|
||||
printf("AI落子(%d, %d)\n", best_x + 1, best_y + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 复盘游戏过程,逐步重现所有落子步骤
|
||||
* @note 实现逻辑:
|
||||
* 1. 创建临时棋盘用于复盘展示
|
||||
* 2. 按步数顺序逐步重现每个落子
|
||||
* 3. 每步显示当前棋盘状态和落子信息
|
||||
* 4. 通过用户按Enter键控制步骤前进
|
||||
* 5. 显示1-based坐标方便用户查看
|
||||
*/
|
||||
void review_process()
|
||||
{
|
||||
printf("\n===== 复盘记录(总步数:%d) =====\n", step_count);
|
||||
// 清空输入缓冲区
|
||||
int c;
|
||||
while ((c = getchar()) != '\n' && c != EOF)
|
||||
;
|
||||
|
||||
// 创建临时复盘棋盘
|
||||
int temp_board[MAX_BOARD_SIZE][MAX_BOARD_SIZE];
|
||||
memset(temp_board, EMPTY, sizeof(temp_board)); // 初始化为空棋盘
|
||||
|
||||
// 逐步重现游戏过程
|
||||
for (int i = 0; i < step_count; i++)
|
||||
{
|
||||
Step s = steps[i]; // 获取当前步骤
|
||||
temp_board[s.x][s.y] = s.player; // 在临时棋盘上落子
|
||||
|
||||
// 打印当前步骤信息
|
||||
printf("\n===== 五子棋人机对战(%dX%d棋盘) =====", BOARD_SIZE, BOARD_SIZE);
|
||||
printf("\n 第%d步/%d步: %s 落子于(%d, %d)\n",
|
||||
i + 1, step_count,
|
||||
(s.player == PLAYER) ? "玩家" : "AI", // 三目运算符选择显示文本
|
||||
s.x + 1, s.y + 1); // 显示1-base坐标
|
||||
|
||||
// 打印当前复盘棋盘
|
||||
printf(" ");
|
||||
for (int col = 0; col < BOARD_SIZE; col++)
|
||||
printf("%2d", col + 1); // 列号
|
||||
printf("\n");
|
||||
|
||||
for (int row = 0; row < BOARD_SIZE; row++)
|
||||
{
|
||||
printf("%2d ", row + 1); // 行号
|
||||
for (int col = 0; col < BOARD_SIZE; col++)
|
||||
{
|
||||
if (temp_board[row][col] == PLAYER)
|
||||
printf("x ");
|
||||
else if (temp_board[row][col] == AI)
|
||||
printf("○ ");
|
||||
else
|
||||
printf("· ");
|
||||
}
|
||||
printf("\n"); // 行结束换行
|
||||
}
|
||||
|
||||
// 如果不是最后一步,等待用户按键继续
|
||||
if (i < step_count - 1)
|
||||
{
|
||||
printf("\n按Enter继续下一步...");
|
||||
while (getchar() != '\n')
|
||||
; // 等待回车
|
||||
}
|
||||
}
|
||||
printf("\n复盘结束!按Enter返回...");
|
||||
getchar(); // 等待用户按键
|
||||
}
|
||||
@@ -1,173 +0,0 @@
|
||||
/**
|
||||
* @file gobang.h
|
||||
* @author 刘航宇(3364451258@qq.com、15236416560@163.com、lhy3364451258@outlook.com)
|
||||
* @brief 五子棋游戏头文件
|
||||
* @version 1.0
|
||||
* @date 2025-06-20
|
||||
*
|
||||
* @copyright Copyright (c) 2025
|
||||
*
|
||||
* @note 本文件为gobang.c的接口文件,提供游戏所需的所有函数声明
|
||||
* @note 设计要点:
|
||||
* 1. 支持5x5到25x25的可变棋盘尺寸
|
||||
* 2. 使用极小极大算法实现AI决策
|
||||
* 3. 提供完整的游戏过程复盘功能
|
||||
* 4. 所有坐标采用0-base索引
|
||||
* 5. 使用全局变量简化状态管理
|
||||
*/
|
||||
|
||||
#ifndef GO_BANG_H
|
||||
#define GO_BANG_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
// 宏定义
|
||||
/**
|
||||
* @brief 最大支持棋盘尺寸
|
||||
* @note 25x25是性能与实用性的平衡点,更大的棋盘会显著降低AI响应速度
|
||||
*/
|
||||
#define MAX_BOARD_SIZE 25 // 最大支持棋盘尺寸(5x5到25x25)
|
||||
|
||||
/**
|
||||
* @brief 玩家标识符
|
||||
* @note 使用1/2而非字符标识,便于扩展为多玩家游戏
|
||||
*/
|
||||
#define PLAYER 1 // 玩家棋子标识符
|
||||
#define AI 2 // AI棋子标识符
|
||||
|
||||
/**
|
||||
* @brief 空位置标识符
|
||||
* @note 必须与PLAYER/AI的值不同
|
||||
*/
|
||||
#define EMPTY 0 // 空位置标识符
|
||||
|
||||
/**
|
||||
* @brief 最大步数限制
|
||||
* @note 等于棋盘总格数,确保不会数组越界
|
||||
*/
|
||||
#define MAX_STEPS (MAX_BOARD_SIZE * MAX_BOARD_SIZE) // 最大步数(棋盘总格数)
|
||||
|
||||
// 全局变量声明
|
||||
extern int BOARD_SIZE; // 实际使用的棋盘尺寸(默认15)
|
||||
extern int board[MAX_BOARD_SIZE][MAX_BOARD_SIZE]; // 棋盘状态存储数组
|
||||
extern int step_count; // 当前步数计数器
|
||||
|
||||
/**
|
||||
* @brief 落子步骤记录结构体
|
||||
* @note 用于存储游戏历史记录和AI决策树
|
||||
* @note 字段说明:
|
||||
* - player: 标识落子方(PLAYER/AI)
|
||||
* - x/y: 0-based坐标位置
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int player; // 落子方标识
|
||||
int x, y; // 坐标位置
|
||||
} Step;
|
||||
|
||||
extern Step steps[MAX_STEPS]; // 存储所有落子步骤的数组
|
||||
|
||||
/**
|
||||
* @brief 连子检测信息结构体
|
||||
* @note 用于五子连珠判断和棋局评估
|
||||
* @note 字段说明:
|
||||
* - continuous_chess: 连续同色棋子数量
|
||||
* - check_start: 序列起点方向是否有空位(可发展性)
|
||||
* - check_end: 序列终点方向是否有空位(可发展性)
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int continuous_chess; // 连续棋子数量
|
||||
bool check_start; // 序列起点方向是否开放(空位)
|
||||
bool check_end; // 序列终点方向是否开放(空位)
|
||||
} DirInfo;
|
||||
|
||||
// 函数声明
|
||||
/**
|
||||
* @brief 初始化棋盘为全空状态
|
||||
*/
|
||||
void empty_board();
|
||||
|
||||
/**
|
||||
* @brief 打印当前棋盘状态
|
||||
*/
|
||||
void print_board();
|
||||
|
||||
/**
|
||||
* @brief 检查指定位置是否为空且有效
|
||||
* @param x 行坐标(0-base)
|
||||
* @param y 列坐标(0-base)
|
||||
* @return true 位置有效且为空
|
||||
* @return false 位置无效或已被占用
|
||||
*/
|
||||
bool have_space(int x, int y);
|
||||
|
||||
/**
|
||||
* @brief 玩家落子操作
|
||||
* @param x 行坐标(0-base)
|
||||
* @param y 列坐标(0-base)
|
||||
* @return true 落子成功
|
||||
* @return false 落子失败(位置无效)
|
||||
*/
|
||||
bool player_move(int x, int y);
|
||||
|
||||
/**
|
||||
* @brief 计算特定方向上连续同色棋子数量
|
||||
* @param x 起始行坐标
|
||||
* @param y 起始列坐标
|
||||
* @param dx 行方向增量(-1,0,1)
|
||||
* @param dy 列方向增量(-1,0,1)
|
||||
* @param player 玩家标识(PLAYER/AI)
|
||||
* @return DirInfo 包含连续棋子数和方向开放状态的结构体
|
||||
*/
|
||||
DirInfo count_specific_direction(int x, int y, int dx, int dy, int player);
|
||||
|
||||
/**
|
||||
* @brief 检查特定位置落子后是否形成五连珠
|
||||
* @param x 行坐标(0-base)
|
||||
* @param y 列坐标(0-base)
|
||||
* @param player 玩家标识(PLAYER/AI)
|
||||
* @return true 形成五连珠
|
||||
* @return false 未形成五连珠
|
||||
*/
|
||||
bool check_win(int x, int y, int player);
|
||||
|
||||
/**
|
||||
* @brief 评估特定位置对当前玩家的价值
|
||||
* @param x 行坐标(0-base)
|
||||
* @param y 列坐标(0-base)
|
||||
* @param player 玩家标识(PLAYER/AI)
|
||||
* @return int 位置评估分数(越高越好)
|
||||
*/
|
||||
int evaluate_pos(int x, int y, int player);
|
||||
|
||||
/**
|
||||
* @brief 带α-β剪枝的深度优先搜索(极小极大算法)
|
||||
* @param x 当前行坐标
|
||||
* @param y 当前列坐标
|
||||
* @param player 当前玩家
|
||||
* @param depth 搜索深度
|
||||
* @param alpha α值(当前最大值)
|
||||
* @param beta β值(当前最小值)
|
||||
* @param is_maximizing 是否为极大化玩家
|
||||
* @return int 最佳评估分数
|
||||
*/
|
||||
int dfs(int x, int y, int player, int depth, int alpha, int beta, bool is_maximizing);
|
||||
|
||||
/**
|
||||
* @brief AI落子决策函数
|
||||
* 使用评估函数和搜索算法选择最佳落子位置
|
||||
*/
|
||||
void ai_move(int depth);
|
||||
|
||||
/**
|
||||
* @brief 复盘游戏过程
|
||||
* 逐步重现游戏中的所有落子步骤
|
||||
*/
|
||||
void review_process();
|
||||
|
||||
#endif // GO_BANG_H
|
||||
@@ -0,0 +1,21 @@
|
||||
# 五子棋游戏配置文件
|
||||
# 棋盘大小 (范围: 5-25)
|
||||
BOARD_SIZE=15
|
||||
|
||||
# 禁手规则 (0=关闭, 1=开启)
|
||||
USE_FORBIDDEN_MOVES=1
|
||||
|
||||
# 计时器 (0=关闭, 1=开启)
|
||||
USE_TIMER=1
|
||||
|
||||
# 时间限制 (分钟)
|
||||
TIME_LIMIT=60
|
||||
|
||||
# 网络端口 (范围: 1024-65535)
|
||||
NETWORK_PORT=8888
|
||||
|
||||
# 网络超时时间 (毫秒)
|
||||
NETWORK_TIMEOUT=5000
|
||||
|
||||
# AI难度 (1-5)
|
||||
AI_DIFFICULTY=3
|
||||
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* @file ai.h
|
||||
* @note 本文件定义了AI模块的函数和变量
|
||||
* @note 包括:
|
||||
* 1. 评估一个落子位置的综合得分(结合进攻和防守)
|
||||
* 2. 评估指定位置的价值
|
||||
* 3. 评估棋盘价值
|
||||
*/
|
||||
|
||||
#ifndef AI_H
|
||||
#define AI_H
|
||||
|
||||
#include "gobang.h"
|
||||
#include "type.h"
|
||||
|
||||
/**
|
||||
* @brief 评估一个落子位置的综合得分(结合进攻和防守)
|
||||
*
|
||||
* @param x 行坐标
|
||||
* @param y 列坐标
|
||||
* @return int 综合得分
|
||||
*/
|
||||
int evaluate_move(int x, int y);
|
||||
|
||||
/**
|
||||
* @brief 评估指定位置的价值
|
||||
*
|
||||
* @param x 位置x坐标
|
||||
* @param y 位置y坐标
|
||||
* @param player 玩家标识(PLAYER/AI)
|
||||
* @return int 位置价值
|
||||
*/
|
||||
int evaluate_pos(int x, int y, int player);
|
||||
|
||||
/**
|
||||
* @brief 评估棋盘价值
|
||||
*
|
||||
* @param player 玩家标识(PLAYER/AI)
|
||||
*/
|
||||
int dfs(int x, int y, int player, int depth, int alpha, int beta, bool is_maximizing);
|
||||
|
||||
/**
|
||||
* @brief AI下棋
|
||||
*
|
||||
* @param depth
|
||||
*/
|
||||
void ai_move(int depth);
|
||||
|
||||
// ==================== AI增强:新增函数声明 ====================
|
||||
|
||||
/**
|
||||
* @brief 生成候选移动并按评估分数排序
|
||||
* @param moves 存储候选移动的数组
|
||||
* @param player 当前玩家
|
||||
* @return 候选移动数量
|
||||
*/
|
||||
int generate_candidate_moves(ScoredMove *moves, int player);
|
||||
|
||||
/**
|
||||
* @brief 检查位置是否在已有棋子附近
|
||||
* @param x, y 要检查的位置
|
||||
* @return 如果附近有棋子返回true
|
||||
*/
|
||||
bool is_near_stones(int x, int y);
|
||||
|
||||
/**
|
||||
* @brief 检测在指定位置落子的威胁等级
|
||||
* @param x, y 落子位置
|
||||
* @param player 落子玩家
|
||||
* @return 威胁等级
|
||||
*/
|
||||
ThreatLevel detect_threat(int x, int y, int player);
|
||||
|
||||
/**
|
||||
* @brief 计算指定方向的威胁数量
|
||||
* @param x, y 起始位置
|
||||
* @param dx, dy 方向向量
|
||||
* @param player 玩家
|
||||
* @return 威胁数量
|
||||
*/
|
||||
int count_threats_in_direction(int x, int y, int dx, int dy, int player);
|
||||
|
||||
#endif // AI_H
|
||||
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @file config.h
|
||||
* @brief 五子棋游戏参数配置头文件
|
||||
* @note 本文件集中定义了五子棋游戏的所有参数配置,便于统一管理和修改
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
//---------- 棋盘相关参数 ----------//
|
||||
#define MAX_BOARD_SIZE 25 // 支持的最大棋盘尺寸
|
||||
#define MIN_BOARD_SIZE 5 // 支持的最小棋盘尺寸
|
||||
#define DEFAULT_BOARD_SIZE 15 // 默认棋盘尺寸
|
||||
#define MAX_STEPS (MAX_BOARD_SIZE * MAX_BOARD_SIZE) // 游戏最大步数
|
||||
|
||||
//---------- 游戏模式参数 ----------//
|
||||
#define GAME_MODE_AI 1 // 人机对战模式
|
||||
#define GAME_MODE_PVP 2 // 双人对战模式
|
||||
#define GAME_MODE_NETWORK 3 // 网络对战模式
|
||||
|
||||
//---------- 玩家标识参数 ----------//
|
||||
#define EMPTY 0 // 棋盘空位标识
|
||||
#define PLAYER 1 // 玩家标识 (用于人机对战模式)
|
||||
#define AI 2 // AI标识 (用于人机对战模式)
|
||||
#define PLAYER1 1 // 玩家1标识 (用于双人对战模式)
|
||||
#define PLAYER2 2 // 玩家2标识 (用于双人对战模式)
|
||||
|
||||
//---------- 特殊输入命令 ----------//
|
||||
#define INPUT_UNDO -1 // 悔棋
|
||||
#define INPUT_SAVE -2 // 保存
|
||||
#define INPUT_EXIT -3 // 退出
|
||||
#define INPUT_SURRENDER -4 // 认输
|
||||
|
||||
//---------- 游戏设置默认值 ----------//
|
||||
#define DEFAULT_USE_FORBIDDEN_MOVES false // 默认不启用禁手规则
|
||||
#define DEFAULT_USE_TIMER 0 // 默认不启用计时器
|
||||
#define DEFAULT_TIME_LIMIT 1800 // 默认时间限制为30分钟(内部以秒存储: 30*60)
|
||||
|
||||
//---------- AI参数 ----------//
|
||||
#define DEFAULT_AI_DEPTH 5 // 默认AI搜索深度
|
||||
#define DEFAULT_DEFENSE_COEFFICIENT 1.5 // 默认防守系数
|
||||
|
||||
//---------- 网络参数 ----------//
|
||||
#define DEFAULT_NETWORK_PORT 8888 // 默认网络端口
|
||||
#define MIN_NETWORK_PORT 1024 // 最小网络端口
|
||||
#define MAX_NETWORK_PORT 65535 // 最大网络端口
|
||||
#define NETWORK_TIMEOUT_MS 5000 // 网络超时时间(毫秒)
|
||||
#define NETWORK_BUFFER_SIZE 1024 // 网络缓冲区大小
|
||||
|
||||
// 网络配置
|
||||
#define MAX_IP_LENGTH 16 // 最大IP地址长度
|
||||
|
||||
// 网络消息类型
|
||||
#define MSG_MOVE 1 // 落子消息
|
||||
#define MSG_CHAT 2 // 聊天消息
|
||||
#define MSG_SURRENDER 3 // 认输消息
|
||||
#define MSG_UNDO_REQUEST 4 // 悔棋请求
|
||||
#define MSG_UNDO_RESPONSE 5 // 悔棋回应
|
||||
#define MSG_GAME_START 6 // 游戏开始
|
||||
#define MSG_GAME_END 7 // 游戏结束
|
||||
#define MSG_HEARTBEAT 8 // 心跳包
|
||||
#define MSG_DISCONNECT 9 // 断线消息
|
||||
|
||||
//---------- 评分参数 ----------//
|
||||
// 棋型评分 - 用于calculate_step_score函数
|
||||
#define SCORE_FIVE 5000 // 五连
|
||||
#define SCORE_LIVE_FOUR 2000 // 活四
|
||||
#define SCORE_RUSH_FOUR 1000 // 冲四
|
||||
#define SCORE_DEAD_FOUR 300 // 死四
|
||||
#define SCORE_LIVE_THREE 500 // 活三
|
||||
#define SCORE_SLEEP_THREE 200 // 眠三
|
||||
#define SCORE_DEAD_THREE 80 // 死三
|
||||
#define SCORE_LIVE_TWO 100 // 活二
|
||||
#define SCORE_SLEEP_TWO 40 // 眠二
|
||||
#define SCORE_DEAD_TWO 15 // 死二
|
||||
#define SCORE_LIVE_ONE 15 // 开放单子
|
||||
#define SCORE_HALF_ONE 8 // 半开放单子
|
||||
#define SCORE_DEAD_ONE 2 // 封闭单子
|
||||
|
||||
// 位置奖励系数
|
||||
#define POSITION_BONUS_FACTOR 10 // 位置奖励因子
|
||||
|
||||
// AI评估参数 - 用于evaluate_pos函数
|
||||
#define AI_SCORE_FIVE 1000000 // AI评估-五连
|
||||
#define AI_SCORE_LIVE_FOUR 100000 // AI评估-活四
|
||||
#define AI_SCORE_RUSH_FOUR 10000 // AI评估-冲四
|
||||
#define AI_SCORE_DEAD_FOUR 500 // AI评估-死四
|
||||
#define AI_SCORE_LIVE_THREE 5000 // AI评估-活三
|
||||
#define AI_SCORE_SLEEP_THREE 1000 // AI评估-眠三
|
||||
#define AI_SCORE_DEAD_THREE 50 // AI评估-死三
|
||||
#define AI_SCORE_LIVE_TWO 500 // AI评估-活二
|
||||
#define AI_SCORE_SLEEP_TWO 100 // AI评估-眠二
|
||||
#define AI_SCORE_DEAD_TWO 10 // AI评估-死二
|
||||
#define AI_SCORE_LIVE_ONE 50 // AI评估-开放单子
|
||||
#define AI_SCORE_HALF_ONE 10 // AI评估-半开放单子
|
||||
#define AI_SCORE_DEAD_ONE 1 // AI评估-封闭单子
|
||||
|
||||
// AI位置奖励系数
|
||||
#define AI_POSITION_BONUS_FACTOR 50 // AI位置奖励因子
|
||||
|
||||
// 搜索算法参数
|
||||
#define SEARCH_MAX_SCORE 1000000 // 搜索最大分数
|
||||
#define SEARCH_WIN_BONUS 1000000 // 获胜奖励分数
|
||||
#define AI_NEARBY_RANGE 3 // AI搜索的邻近范围
|
||||
#define AI_SEARCH_RANGE_THRESHOLD 8 // AI开始限制搜索范围的步数阈值
|
||||
|
||||
// 组合棋型评分 - AI增强新增
|
||||
#define AI_SCORE_DOUBLE_THREE 50000 // 双三
|
||||
#define AI_SCORE_FOUR_THREE 200000 // 四三
|
||||
#define AI_SCORE_THREAT_SEQUENCE 80000 // 威胁序列
|
||||
#define AI_SCORE_POTENTIAL_FIVE 300000 // 潜在五连
|
||||
|
||||
// 评分权重参数
|
||||
#define TIME_WEIGHT_FACTOR 0.5 // 时间权重因子
|
||||
#define WIN_BONUS 2000 // 胜利奖励分数
|
||||
|
||||
//---------- GUI界面参数 ----------//
|
||||
// 窗口和棋盘配置
|
||||
#define WINDOW_WIDTH 1000
|
||||
#define WINDOW_HEIGHT 800
|
||||
#define BOARD_OFFSET_X 50
|
||||
#define BOARD_OFFSET_Y 50
|
||||
#define CELL_SIZE 30
|
||||
#define STONE_RADIUS 12
|
||||
|
||||
// 颜色定义
|
||||
#define GUI_COLOR_BACKGROUND {240, 217, 181, 255}
|
||||
#define GUI_COLOR_BOARD_LINE {0, 0, 0, 255}
|
||||
#define GUI_COLOR_BLACK_STONE {0, 0, 0, 255}
|
||||
#define GUI_COLOR_WHITE_STONE {255, 255, 255, 255}
|
||||
#define GUI_COLOR_STONE_BORDER {100, 100, 100, 255}
|
||||
|
||||
//---------- 文件路径参数 ----------//
|
||||
#define RECORDS_DIR "records" // 记录文件目录
|
||||
#define CONFIG_FILE "gobang_config.ini" // 配置文件路径
|
||||
#define MAX_PATH_LENGTH 256 // 最大路径长度
|
||||
|
||||
//---------- 配置管理函数声明 ----------//
|
||||
/**
|
||||
* @brief 加载游戏配置
|
||||
*/
|
||||
void load_game_config();
|
||||
|
||||
/**
|
||||
* @brief 保存游戏配置
|
||||
*/
|
||||
void save_game_config();
|
||||
|
||||
/**
|
||||
* @brief 重置为默认配置
|
||||
*/
|
||||
void reset_to_default_config();
|
||||
|
||||
#endif // CONFIG_H
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* @file globals.h
|
||||
* @brief 全局变量声明头文件
|
||||
* @note 集中管理所有全局变量的声明,提高代码可维护性
|
||||
*/
|
||||
|
||||
#ifndef GLOBALS_H
|
||||
#define GLOBALS_H
|
||||
|
||||
#include "type.h"
|
||||
#include "gobang.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
// ==================== 游戏核心变量 ====================
|
||||
extern int BOARD_SIZE; // 当前实际使用的棋盘尺寸
|
||||
extern int board[MAX_BOARD_SIZE][MAX_BOARD_SIZE]; // 棋盘状态存储数组
|
||||
extern Step steps[MAX_STEPS]; // 存储所有落子步骤的数组
|
||||
extern const int direction[4][2]; // 四个方向:向下、向右、右下、左下
|
||||
extern int step_count; // 当前步数计数器
|
||||
|
||||
// ==================== 游戏配置变量 ====================
|
||||
extern bool use_forbidden_moves; // 是否启用禁手规则的标志
|
||||
extern int use_timer; // 是否启用计时器的标志
|
||||
extern int time_limit; // 每回合的时间限制(秒,内部存储)
|
||||
extern int network_port; // 网络端口
|
||||
extern int network_timeout; // 网络超时时间
|
||||
|
||||
// ==================== AI相关变量 ====================
|
||||
extern double defense_coefficient; // 防守系数
|
||||
extern int ai_difficulty; // AI难度 (1-5)
|
||||
|
||||
// ==================== 网络相关变量 ====================
|
||||
extern NetworkGameState network_state; // 网络游戏状态
|
||||
|
||||
// ==================== GUI相关变量 ====================
|
||||
extern int current_player_gui; // GUI当前玩家
|
||||
extern int game_over; // 游戏结束标志
|
||||
extern char status_message[256]; // 状态消息
|
||||
|
||||
// ==================== 记录相关变量 ====================
|
||||
extern int player1_final_score; // 玩家1最终得分
|
||||
extern int player2_final_score; // 玩家2最终得分
|
||||
extern int scores_calculated; // 评分计算标志
|
||||
extern char winner_info[50]; // 存储胜负信息
|
||||
|
||||
#endif // GLOBALS_H
|
||||
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* @file gobang.h
|
||||
* @brief 五子棋游戏头文件
|
||||
* @note 本文件定义了五子棋游戏的主要数据结构、函数和全局变量。
|
||||
* 它包含了游戏棋盘的表示、玩家操作、规则检查以及AI决策等功能。
|
||||
*/
|
||||
|
||||
#ifndef GO_BANG_H
|
||||
#define GO_BANG_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include "config.h"
|
||||
#include "type.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
|
||||
// 函数原型
|
||||
|
||||
// --- 游戏核心逻辑 ---
|
||||
/**
|
||||
* @brief 初始化棋盘,将所有位置设置为空(EMPTY)
|
||||
*/
|
||||
void empty_board();
|
||||
|
||||
/**
|
||||
* @brief 检查指定坐标是否为有效落子点(在棋盘内且为空)
|
||||
* @param x 待检查的行坐标 (0-based)
|
||||
* @param y 待检查的列坐标 (0-based)
|
||||
* @return 若位置有效且为空则返回true,否则返回false
|
||||
*/
|
||||
bool have_space(int x, int y);
|
||||
|
||||
/**
|
||||
* @brief 判断一个落子是否为禁手
|
||||
* @param x 落子的行坐标 (0-based)
|
||||
* @param y 落子的列坐标 (0-based)
|
||||
* @param player 当前玩家的标识
|
||||
* @return 如果是禁手则返回true,否则返回false
|
||||
*/
|
||||
bool is_forbidden_move(int x, int y, int player);
|
||||
|
||||
|
||||
/**
|
||||
* @brief 执行一次玩家落子操作
|
||||
* @param x 落子的行坐标 (0-based)
|
||||
* @param y 落子的列坐标 (0-based)
|
||||
* @param player 当前玩家的标识
|
||||
* @return 若落子成功则返回true,否则(位置无效或被占用)返回false
|
||||
*/
|
||||
bool player_move(int x, int y, int player);
|
||||
|
||||
/**
|
||||
* @brief 计算在特定方向上的棋子连续信息
|
||||
* @param x 起始点的行坐标
|
||||
* @param y 起始点的列坐标
|
||||
* @param dx x方向的增量 (-1, 0, or 1)
|
||||
* @param dy y方向的增量 (-1, 0, or 1)
|
||||
* @param player 玩家标识
|
||||
* @return 返回一个包含连续棋子信息的 DirInfo 结构体
|
||||
*/
|
||||
DirInfo count_specific_direction(int x, int y, int dx, int dy, int player);
|
||||
|
||||
/**
|
||||
* @brief 检查在某点落子后,该玩家是否获胜
|
||||
* @param x 落子的行坐标 (0-based)
|
||||
* @param y 落子的列坐标 (0-based)
|
||||
* @param player 当前玩家的标识
|
||||
* @return 如果获胜则返回true,否则返回false
|
||||
*/
|
||||
bool check_win(int x, int y, int player);
|
||||
|
||||
/**
|
||||
* @brief 悔棋功能,撤销指定步数
|
||||
* @param steps_to_undo 要撤销的步数(每步包含双方各一次落子)
|
||||
* @return 若悔棋成功则返回true,否则返回false
|
||||
*/
|
||||
bool return_move(int steps_to_undo);
|
||||
|
||||
/**
|
||||
* @brief 计算并返回一步棋的得分
|
||||
* @param x 落子的行坐标
|
||||
* @param y 落子的列坐标
|
||||
* @param player 玩家标识
|
||||
* @return 该步棋的得分
|
||||
*/
|
||||
int calculate_step_score(int x, int y, int player);
|
||||
|
||||
#endif // GO_BANG_H
|
||||
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* @file gui.h
|
||||
* @brief 图形化用户界面头文件
|
||||
* @note 使用IUP库实现五子棋的图形化界面
|
||||
* @author 刘航宇
|
||||
*/
|
||||
|
||||
#ifndef GUI_H
|
||||
#define GUI_H
|
||||
|
||||
#include "gobang.h"
|
||||
#include "config.h"
|
||||
#include "globals.h"
|
||||
|
||||
// GUI函数声明
|
||||
|
||||
/**
|
||||
* @brief 初始化GUI
|
||||
* @details 初始化IUP图形库和游戏界面组件
|
||||
* @return 成功返回0,失败返回-1
|
||||
*/
|
||||
int init_gui();
|
||||
|
||||
/**
|
||||
* @brief 清理GUI资源
|
||||
*/
|
||||
void cleanup_gui();
|
||||
|
||||
/**
|
||||
* @brief 屏幕坐标转棋盘坐标
|
||||
*/
|
||||
int screen_to_board(int screen_x, int screen_y, int *board_x, int *board_y);
|
||||
|
||||
/**
|
||||
* @brief 显示消息
|
||||
*/
|
||||
void show_message(const char *message);
|
||||
|
||||
/**
|
||||
* @brief 启动玩家对战模式
|
||||
*/
|
||||
void start_pvp_game_gui();
|
||||
|
||||
/**
|
||||
* @brief 启动人机对战模式
|
||||
*/
|
||||
void start_pve_game_gui();
|
||||
|
||||
/**
|
||||
* @brief 启动复盘模式
|
||||
*/
|
||||
void start_replay_gui();
|
||||
|
||||
/**
|
||||
* @brief 运行图形化界面模式
|
||||
* @details 主循环处理事件、渲染画面和更新状态
|
||||
*/
|
||||
void run_gui_mode();
|
||||
|
||||
#endif // GUI_H
|
||||
@@ -0,0 +1,42 @@
|
||||
#ifndef GUI_INTERNAL_H
|
||||
#define GUI_INTERNAL_H
|
||||
|
||||
#include <iup.h>
|
||||
|
||||
// 全局变量声明 (在 gui_core.c 中定义)
|
||||
extern Ihandle *dlg;
|
||||
extern Ihandle *board_canvas;
|
||||
extern Ihandle *lbl_player;
|
||||
extern Ihandle *lbl_status;
|
||||
extern int gui_game_mode; // 0: PvP, 1: PvE, 2: Replay
|
||||
extern int replay_total_steps; // 复盘总步数
|
||||
|
||||
// 绘图函数 (在 gui_draw.c 中定义)
|
||||
void set_draw_color(Ihandle *ih, unsigned char r, unsigned char g, unsigned char b);
|
||||
void draw_board_iup(Ihandle *ih);
|
||||
void draw_stones_iup(Ihandle *ih);
|
||||
|
||||
// 核心功能 (在 gui_core.c 中定义)
|
||||
void update_ui_labels();
|
||||
int screen_to_board(int screen_x, int screen_y, int *board_x, int *board_y);
|
||||
|
||||
// 游戏窗口 (在 gui_game.c 中定义)
|
||||
void create_game_window();
|
||||
void start_pvp_game_gui();
|
||||
void start_pve_game_gui();
|
||||
void start_network_game_gui(); // 新增:启动网络对战游戏窗口
|
||||
int action_cb(Ihandle *ih);
|
||||
int button_cb(Ihandle *ih, int button, int pressed, int x, int y, char *status);
|
||||
int k_any_cb(Ihandle *ih, int c);
|
||||
int btn_back_cb(Ihandle *ih);
|
||||
int btn_undo_cb(Ihandle *ih);
|
||||
int btn_save_cb(Ihandle *ih);
|
||||
|
||||
// 复盘功能 (在 gui_replay.c 中定义)
|
||||
void select_replay_file_gui();
|
||||
int btn_replay_prev_cb(Ihandle *ih);
|
||||
int btn_replay_next_cb(Ihandle *ih);
|
||||
int btn_replay_sel_ok_cb(Ihandle *ih);
|
||||
int btn_replay_sel_cancel_cb(Ihandle *ih);
|
||||
|
||||
#endif // GUI_INTERNAL_H
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef GUI_MENU_H
|
||||
#define GUI_MENU_H
|
||||
|
||||
#include <iup.h>
|
||||
|
||||
// 主菜单对话框句柄,需要暴露给其他模块(如返回菜单时)
|
||||
extern Ihandle *menu_dlg;
|
||||
|
||||
/**
|
||||
* @brief 创建并显示主菜单
|
||||
*/
|
||||
void create_main_menu();
|
||||
|
||||
/**
|
||||
* @brief 显示主菜单
|
||||
*/
|
||||
void show_main_menu();
|
||||
|
||||
/**
|
||||
* @brief 隐藏主菜单
|
||||
*/
|
||||
void hide_main_menu();
|
||||
|
||||
#endif // GUI_MENU_H
|
||||
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* @file network.h
|
||||
* @brief 五子棋网络对战模块头文件
|
||||
* @note 本文件定义了五子棋游戏的网络对战功能:
|
||||
* 1. 服务器模式(主机)
|
||||
* 2. 客户端模式(加入游戏)
|
||||
* 3. 网络消息传输
|
||||
*/
|
||||
|
||||
#ifndef NETWORK_H
|
||||
#define NETWORK_H
|
||||
|
||||
#include "type.h"
|
||||
#include "config.h"
|
||||
#include <stdbool.h>
|
||||
#include <enet/enet.h> // 引入 ENet 头文件
|
||||
|
||||
// 网络状态结构体在 type.h 中定义,我们需要修改 type.h 来包含 ENet 类型
|
||||
// 或者在这里重新定义(如果 type.h 中可以移除旧的定义)
|
||||
|
||||
// 全局网络状态
|
||||
extern NetworkGameState network_state;
|
||||
|
||||
// 函数声明
|
||||
|
||||
/**
|
||||
* @brief 初始化网络模块
|
||||
* @return true 初始化成功
|
||||
* @return false 初始化失败
|
||||
*/
|
||||
bool init_network();
|
||||
|
||||
/**
|
||||
* @brief 清理网络模块
|
||||
*/
|
||||
void cleanup_network();
|
||||
|
||||
/**
|
||||
* @brief 创建服务器(主机模式)
|
||||
* @param port 监听端口
|
||||
* @return true 创建成功
|
||||
* @return false 创建失败
|
||||
*/
|
||||
bool create_server(int port);
|
||||
|
||||
/**
|
||||
* @brief 连接到服务器(客户端模式)
|
||||
* @param ip 服务器IP地址
|
||||
* @param port 服务器端口
|
||||
* @return true 连接成功
|
||||
* @return false 连接失败
|
||||
*/
|
||||
bool connect_to_server(const char *ip, int port);
|
||||
|
||||
/**
|
||||
* @brief 发送网络消息
|
||||
* @param msg 要发送的消息
|
||||
* @return true 发送成功
|
||||
* @return false 发送失败
|
||||
*/
|
||||
bool send_network_message(const NetworkMessage *msg);
|
||||
|
||||
/**
|
||||
* @brief 接收网络消息
|
||||
* @param msg 接收消息的缓冲区
|
||||
* @param timeout_ms 超时时间(毫秒),0表示不阻塞等待
|
||||
* @return true 接收成功
|
||||
* @return false 接收失败或超时
|
||||
*/
|
||||
bool receive_network_message(NetworkMessage *msg, int timeout_ms);
|
||||
|
||||
/**
|
||||
* @brief 断开网络连接
|
||||
*/
|
||||
void disconnect_network();
|
||||
|
||||
/**
|
||||
* @brief 检查网络连接状态
|
||||
* @return true 连接正常
|
||||
* @return false 连接断开
|
||||
*/
|
||||
bool is_network_connected();
|
||||
|
||||
/**
|
||||
* @brief 获取本机IP地址
|
||||
* @param ip_buffer 存储IP地址的缓冲区
|
||||
* @param buffer_size 缓冲区大小
|
||||
* @return true 获取成功
|
||||
* @return false 获取失败
|
||||
*/
|
||||
bool get_local_ip(char *ip_buffer, int buffer_size);
|
||||
|
||||
/**
|
||||
* @brief 发送落子消息
|
||||
* @param x 行坐标
|
||||
* @param y 列坐标
|
||||
* @param player_id 玩家ID
|
||||
* @return true 发送成功
|
||||
* @return false 发送失败
|
||||
*/
|
||||
bool send_move(int x, int y, int player_id);
|
||||
|
||||
/**
|
||||
* @brief 发送聊天消息
|
||||
* @param message 聊天内容
|
||||
* @return true 发送成功
|
||||
* @return false 发送失败
|
||||
*/
|
||||
bool send_chat_message(const char *message);
|
||||
|
||||
/**
|
||||
* @brief 发送认输消息
|
||||
* @return true 发送成功
|
||||
* @return false 发送失败
|
||||
*/
|
||||
bool send_surrender();
|
||||
|
||||
/**
|
||||
* @brief 发送悔棋请求
|
||||
* @param steps 悔棋步数
|
||||
* @return true 发送成功
|
||||
* @return false 发送失败
|
||||
*/
|
||||
bool send_undo_request(int steps);
|
||||
|
||||
/**
|
||||
* @brief 发送悔棋回应
|
||||
* @param accepted 是否同意悔棋
|
||||
* @param steps 悔棋步数
|
||||
* @return true 发送成功
|
||||
* @return false 发送失败
|
||||
*/
|
||||
bool send_undo_response(bool accepted, int steps);
|
||||
|
||||
#endif // NETWORK_H
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* @file record.h
|
||||
* @brief 游戏复盘与记录头文件
|
||||
* @note 本文件定义了游戏复盘与记录相关的函数和数据结构。
|
||||
* 它负责管理游戏的历史记录、加载和保存游戏文件、计算游戏评分等功能。
|
||||
*/
|
||||
#ifndef RECORD_H
|
||||
#define RECORD_H
|
||||
|
||||
#include "gobang.h"
|
||||
|
||||
// --- 复盘与记录功能 ---
|
||||
/**
|
||||
* @brief 将当前对局记录保存到文件
|
||||
* @param filename 要保存到的文件名
|
||||
* @param game_mode 游戏模式
|
||||
* @return 0表示成功,非0表示失败
|
||||
*/
|
||||
int save_game_to_file(const char *filename, int game_mode);
|
||||
|
||||
/**
|
||||
* @brief 从文件加载游戏记录
|
||||
* @param filename 要加载的文件名
|
||||
* @return 游戏模式(1或2),0表示失败
|
||||
*/
|
||||
int load_game_from_file(const char *filename);
|
||||
|
||||
/**
|
||||
* @brief 计算游戏评分
|
||||
*/
|
||||
void calculate_game_scores();
|
||||
|
||||
/**
|
||||
* @brief 显示游戏评分结果和MVP评选
|
||||
* @param game_mode 游戏模式(1-人机对战,2-双人对战)
|
||||
*/
|
||||
void display_game_scores(int game_mode);
|
||||
|
||||
#endif // RECORD_H
|
||||
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* @file type.h
|
||||
* @brief 五子棋游戏数据类型定义头文件
|
||||
* @note 本文件集中定义了五子棋游戏中使用的所有数据结构和枚举类型
|
||||
* @author 刘航宇
|
||||
*/
|
||||
|
||||
#ifndef TYPE_H
|
||||
#define TYPE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// ==================== 游戏核心数据结构 ====================
|
||||
|
||||
/**
|
||||
* @brief 记录一步棋的详细信息
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int player; // 执行该步的玩家标识
|
||||
int x; // 落子的行坐标 (0-based)
|
||||
int y; // 落子的列坐标 (0-based)
|
||||
} Step;
|
||||
|
||||
/**
|
||||
* @brief 存储在特定方向上棋子连续性的信息
|
||||
* @details 用于评估棋形,例如判断活三、冲四等关键形态
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int continuous_chess; // 连续同色棋子的数量
|
||||
bool check_start; // 棋子序列的起始端是否为空位(即是否开放)
|
||||
bool check_end; // 棋子序列的末尾端是否为空位(即是否开放)
|
||||
} DirInfo;
|
||||
|
||||
// ==================== AI相关数据结构 ====================
|
||||
|
||||
/**
|
||||
* @brief 移动排序结构体
|
||||
* @details 用于AI移动排序,存储候选移动及其评估分数
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int x, y; // 位置坐标
|
||||
int score; // 评估分数
|
||||
} ScoredMove;
|
||||
|
||||
/**
|
||||
* @brief 威胁类型枚举
|
||||
* @details 用于AI威胁检测系统
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
THREAT_NONE = 0, // 无威胁
|
||||
THREAT_WIN = 5, // 直接获胜
|
||||
THREAT_FOUR = 4, // 活四/冲四
|
||||
THREAT_THREE = 3, // 活三
|
||||
THREAT_DOUBLE = 2, // 双威胁
|
||||
THREAT_POTENTIAL = 1 // 潜在威胁
|
||||
} ThreatLevel;
|
||||
|
||||
// ==================== 网络相关数据结构 ====================
|
||||
|
||||
/**
|
||||
* @brief 网络消息结构
|
||||
* @details 用于网络对战中的消息传输
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int type; // 消息类型
|
||||
int player_id; // 玩家ID
|
||||
int x, y; // 坐标(用于落子)
|
||||
char message[256]; // 消息内容(用于聊天等)
|
||||
time_t timestamp; // 时间戳
|
||||
} NetworkMessage;
|
||||
|
||||
/**
|
||||
* @brief 网络游戏状态结构
|
||||
* @details 用于管理网络游戏状态
|
||||
*/
|
||||
// ENet 头文件需要前置声明或直接包含,但在 type.h 中包含可能引起循环依赖
|
||||
// 我们可以使用 void* 来避免在 type.h 中包含 enet.h
|
||||
typedef struct
|
||||
{
|
||||
void *host; // ENetHost * (Server 或 Client)
|
||||
void *peer; // ENetPeer * (连接的对象)
|
||||
bool is_server; // 是否为服务器(主机)
|
||||
bool is_connected; // 是否已连接
|
||||
int local_player_id; // 本地玩家ID
|
||||
int remote_player_id; // 远程玩家ID
|
||||
char remote_ip[64]; // 远程IP
|
||||
int port; // 端口
|
||||
} NetworkGameState;
|
||||
|
||||
#endif // TYPE_H
|
||||
@@ -0,0 +1,43 @@
|
||||
[Setup]
|
||||
AppName=五子棋游戏
|
||||
AppVersion=8.3
|
||||
AppPublisher=LHY
|
||||
AppPublisherURL=https://github.com/LHY0125/gobang.git
|
||||
AppSupportURL=https://github.com/LHY0125/gobang.git
|
||||
AppUpdatesURL=https://github.com/LHY0125/gobang.git
|
||||
DefaultDirName={autopf}\Gobang
|
||||
DefaultGroupName=五子棋游戏
|
||||
AllowNoIcons=yes
|
||||
OutputDir=dist
|
||||
OutputBaseFilename=Gobang_Inno_Setup
|
||||
SetupIconFile=
|
||||
Compression=lzma
|
||||
SolidCompression=yes
|
||||
WizardStyle=modern
|
||||
PrivilegesRequired=lowest
|
||||
|
||||
[Languages]
|
||||
Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||
|
||||
[Tasks]
|
||||
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
|
||||
|
||||
[Files]
|
||||
Source: "..\bin\gobang_gui.exe"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "..\bin\iup.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||
; 允许文件夹为空时不报错
|
||||
Source: "..\bin\records\*"; DestDir: "{app}\records"; Flags: ignoreversion recursesubdirs createallsubdirs skipifsourcedoesntexist
|
||||
|
||||
[Icons]
|
||||
Name: "{group}\五子棋游戏(图形界面版)"; Filename: "{app}\gobang_gui.exe"; WorkingDir: "{app}"
|
||||
Name: "{group}\{cm:UninstallProgram,五子棋游戏}"; Filename: "{uninstallexe}"
|
||||
Name: "{autodesktop}\五子棋游戏"; Filename: "{app}\gobang_gui.exe"; WorkingDir: "{app}"; Tasks: desktopicon
|
||||
|
||||
[Run]
|
||||
Filename: "{app}\gobang_gui.exe"; WorkingDir: "{app}"; Description: "{cm:LaunchProgram,五子棋游戏}"; Flags: nowait postinstall skipifsilent
|
||||
|
||||
[UninstallDelete]
|
||||
Type: filesandordirs; Name: "{app}\records"
|
||||
Type: files; Name: "{app}\gobang_gui.exe"
|
||||
Type: files; Name: "{app}\iup.dll"
|
||||
Type: dirifempty; Name: "{app}"
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
on: [push, pull_request]
|
||||
|
||||
name: CMake
|
||||
|
||||
jobs:
|
||||
cmake-build:
|
||||
name: CMake ${{ matrix.os }} ${{ matrix.build_type }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: ["ubuntu-latest", "windows-latest", "macos-latest"]
|
||||
build_type: ["Debug", "Release"]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Configure CMake
|
||||
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
|
||||
|
||||
- name: Build
|
||||
run: cmake --build ${{github.workspace}}/build --config ${{ matrix.build_type }}
|
||||
@@ -0,0 +1,70 @@
|
||||
# Potential build directories
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
[Bb]in/
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
[Oo]bj/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
[Ww][Ii][Nn]32/
|
||||
bld/
|
||||
build/
|
||||
builds/
|
||||
out/
|
||||
x64/
|
||||
x86/
|
||||
|
||||
# VS
|
||||
.vs/
|
||||
.vscode/
|
||||
!.vscode/extensions.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
|
||||
# CMake
|
||||
_deps
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
CMakeLists.txt.user
|
||||
CMakeScripts
|
||||
CMakeUserPresets.json
|
||||
CTestTestfile.cmake
|
||||
cmake_install.cmake
|
||||
compile_commands.json
|
||||
install_manifest.txt
|
||||
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
@@ -0,0 +1,119 @@
|
||||
cmake_minimum_required(VERSION 2.8.12...3.20)
|
||||
|
||||
project(enet)
|
||||
|
||||
# The "configure" step.
|
||||
include(CheckFunctionExists)
|
||||
include(CheckStructHasMember)
|
||||
include(CheckTypeSize)
|
||||
check_function_exists("fcntl" HAS_FCNTL)
|
||||
check_function_exists("poll" HAS_POLL)
|
||||
check_function_exists("getaddrinfo" HAS_GETADDRINFO)
|
||||
check_function_exists("getnameinfo" HAS_GETNAMEINFO)
|
||||
check_function_exists("gethostbyname_r" HAS_GETHOSTBYNAME_R)
|
||||
check_function_exists("gethostbyaddr_r" HAS_GETHOSTBYADDR_R)
|
||||
check_function_exists("inet_pton" HAS_INET_PTON)
|
||||
check_function_exists("inet_ntop" HAS_INET_NTOP)
|
||||
check_c_source_compiles("
|
||||
#include <stddef.h>
|
||||
struct S { int a; double b; };
|
||||
int main() {
|
||||
return (int)offsetof(struct S, b);
|
||||
}
|
||||
" HAS_OFFSETOF)
|
||||
check_struct_has_member("struct msghdr" "msg_flags" "sys/types.h;sys/socket.h" HAS_MSGHDR_FLAGS)
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES "sys/types.h" "sys/socket.h")
|
||||
check_type_size("socklen_t" HAS_SOCKLEN_T BUILTIN_TYPES_ONLY)
|
||||
unset(CMAKE_EXTRA_INCLUDE_FILES)
|
||||
if(MSVC)
|
||||
add_definitions(-W3)
|
||||
else()
|
||||
add_definitions(-Wno-error)
|
||||
endif()
|
||||
|
||||
if(HAS_FCNTL)
|
||||
add_definitions(-DHAS_FCNTL=1)
|
||||
endif()
|
||||
if(HAS_POLL)
|
||||
add_definitions(-DHAS_POLL=1)
|
||||
endif()
|
||||
if(HAS_GETNAMEINFO)
|
||||
add_definitions(-DHAS_GETNAMEINFO=1)
|
||||
endif()
|
||||
if(HAS_GETADDRINFO)
|
||||
add_definitions(-DHAS_GETADDRINFO=1)
|
||||
endif()
|
||||
if(HAS_GETHOSTBYNAME_R)
|
||||
add_definitions(-DHAS_GETHOSTBYNAME_R=1)
|
||||
endif()
|
||||
if(HAS_GETHOSTBYADDR_R)
|
||||
add_definitions(-DHAS_GETHOSTBYADDR_R=1)
|
||||
endif()
|
||||
if(HAS_INET_PTON)
|
||||
add_definitions(-DHAS_INET_PTON=1)
|
||||
endif()
|
||||
if(HAS_INET_NTOP)
|
||||
add_definitions(-DHAS_INET_NTOP=1)
|
||||
endif()
|
||||
if(HAS_OFFSETOF)
|
||||
add_definitions(-DHAS_OFFSETOF=1)
|
||||
endif()
|
||||
if(HAS_MSGHDR_FLAGS)
|
||||
add_definitions(-DHAS_MSGHDR_FLAGS=1)
|
||||
endif()
|
||||
if(HAS_SOCKLEN_T)
|
||||
add_definitions(-DHAS_SOCKLEN_T=1)
|
||||
endif()
|
||||
|
||||
include_directories(${PROJECT_SOURCE_DIR}/include)
|
||||
|
||||
set(INCLUDE_FILES_PREFIX include/enet)
|
||||
set(INCLUDE_FILES
|
||||
${INCLUDE_FILES_PREFIX}/callbacks.h
|
||||
${INCLUDE_FILES_PREFIX}/enet.h
|
||||
${INCLUDE_FILES_PREFIX}/list.h
|
||||
${INCLUDE_FILES_PREFIX}/protocol.h
|
||||
${INCLUDE_FILES_PREFIX}/time.h
|
||||
${INCLUDE_FILES_PREFIX}/types.h
|
||||
${INCLUDE_FILES_PREFIX}/unix.h
|
||||
${INCLUDE_FILES_PREFIX}/utility.h
|
||||
${INCLUDE_FILES_PREFIX}/win32.h
|
||||
)
|
||||
|
||||
set(SOURCE_FILES
|
||||
callbacks.c
|
||||
compress.c
|
||||
host.c
|
||||
list.c
|
||||
packet.c
|
||||
peer.c
|
||||
protocol.c
|
||||
unix.c
|
||||
win32.c)
|
||||
|
||||
source_group(include FILES ${INCLUDE_FILES})
|
||||
source_group(source FILES ${SOURCE_FILES})
|
||||
|
||||
if(WIN32 AND BUILD_SHARED_LIBS AND (MSVC OR CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
|
||||
add_definitions(-DENET_DLL=1)
|
||||
add_definitions(-DENET_BUILDING_LIB)
|
||||
endif()
|
||||
|
||||
add_library(enet
|
||||
${INCLUDE_FILES}
|
||||
${SOURCE_FILES}
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
target_link_libraries(enet winmm ws2_32)
|
||||
endif()
|
||||
|
||||
include(GNUInstallDirs)
|
||||
install(TARGETS enet
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
)
|
||||
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/enet
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
)
|
||||
@@ -0,0 +1,209 @@
|
||||
ENet 1.3.18 (April 14, 2024):
|
||||
|
||||
* Packet sending performance improvements
|
||||
* MTU negotiation fixes
|
||||
* Checksum alignment fix
|
||||
* No more dynamic initialization of checksum table
|
||||
* ENET_SOCKOPT_TTL
|
||||
* Other miscellaneous small improvements
|
||||
|
||||
ENet 1.3.17 (November 15, 2020):
|
||||
|
||||
* fixes for sender getting too far ahead of receiver that can cause instability with reliable packets
|
||||
|
||||
ENet 1.3.16 (September 8, 2020):
|
||||
|
||||
* fix bug in unreliable fragment queuing
|
||||
* use single output queue for reliable and unreliable packets for saner ordering
|
||||
* revert experimental throttle changes that were less stable than prior algorithm
|
||||
|
||||
ENet 1.3.15 (April 20, 2020):
|
||||
|
||||
* quicker RTT initialization
|
||||
* use fractional precision for RTT calculations
|
||||
* fixes for packet throttle with low RTT variance
|
||||
* miscellaneous socket bug fixes
|
||||
|
||||
ENet 1.3.14 (January 27, 2019):
|
||||
|
||||
* bug fix for enet_peer_disconnect_later()
|
||||
* use getaddrinfo and getnameinfo where available
|
||||
* miscellaneous cleanups
|
||||
|
||||
ENet 1.3.13 (April 30, 2015):
|
||||
|
||||
* miscellaneous bug fixes
|
||||
* added premake and cmake support
|
||||
* miscellaneous documentation cleanups
|
||||
|
||||
ENet 1.3.12 (April 24, 2014):
|
||||
|
||||
* added maximumPacketSize and maximumWaitingData fields to ENetHost to limit the amount of
|
||||
data waiting to be delivered on a peer (beware that the default maximumPacketSize is
|
||||
32MB and should be set higher if desired as should maximumWaitingData)
|
||||
|
||||
ENet 1.3.11 (December 26, 2013):
|
||||
|
||||
* allow an ENetHost to connect to itself
|
||||
* fixed possible bug with disconnect notifications during connect attempts
|
||||
* fixed some preprocessor definition bugs
|
||||
|
||||
ENet 1.3.10 (October 23, 2013);
|
||||
|
||||
* doubled maximum reliable window size
|
||||
* fixed RCVTIMEO/SNDTIMEO socket options and also added NODELAY
|
||||
|
||||
ENet 1.3.9 (August 19, 2013):
|
||||
|
||||
* added duplicatePeers option to ENetHost which can limit the number of peers from duplicate IPs
|
||||
* added enet_socket_get_option() and ENET_SOCKOPT_ERROR
|
||||
* added enet_host_random_seed() platform stub
|
||||
|
||||
ENet 1.3.8 (June 2, 2013):
|
||||
|
||||
* added enet_linked_version() for checking the linked version
|
||||
* added enet_socket_get_address() for querying the local address of a socket
|
||||
* silenced some debugging prints unless ENET_DEBUG is defined during compilation
|
||||
* handle EINTR in enet_socket_wait() so that enet_host_service() doesn't propagate errors from signals
|
||||
* optimized enet_host_bandwidth_throttle() to be less expensive for large numbers of peers
|
||||
|
||||
ENet 1.3.7 (March 6, 2013):
|
||||
|
||||
* added ENET_PACKET_FLAG_SENT to indicate that a packet is being freed because it has been sent
|
||||
* added userData field to ENetPacket
|
||||
* changed how random seed is generated on Windows to avoid import warnings
|
||||
* fixed case where disconnects could be generated with no preceding connect event
|
||||
|
||||
ENet 1.3.6 (December 11, 2012):
|
||||
|
||||
* added support for intercept callback in ENetHost that can be used to process raw packets before ENet
|
||||
* added enet_socket_shutdown() for issuing shutdown on a socket
|
||||
* fixed enet_socket_connect() to not error on non-blocking connects
|
||||
* fixed bug in MTU negotiation during connections
|
||||
|
||||
ENet 1.3.5 (July 31, 2012):
|
||||
|
||||
* fixed bug in unreliable packet fragment queuing
|
||||
|
||||
ENet 1.3.4 (May 29, 2012):
|
||||
|
||||
* added enet_peer_ping_interval() for configuring per-peer ping intervals
|
||||
* added enet_peer_timeout() for configuring per-peer timeouts
|
||||
* added protocol packet size limits
|
||||
|
||||
ENet 1.3.3 (June 28, 2011):
|
||||
|
||||
* fixed bug with simultaneous disconnects not dispatching events
|
||||
|
||||
ENet 1.3.2 (May 31, 2011):
|
||||
|
||||
* added support for unreliable packet fragmenting via the packet flag
|
||||
ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT
|
||||
* fixed regression in unreliable packet queuing
|
||||
* added check against received port to limit some forms of IP-spoofing
|
||||
|
||||
ENet 1.3.1 (February 10, 2011):
|
||||
|
||||
* fixed bug in tracking of reliable data in transit
|
||||
* reliable data window size now scales with the throttle
|
||||
* fixed bug in fragment length calculation when checksums are used
|
||||
|
||||
ENet 1.3.0 (June 5, 2010):
|
||||
|
||||
* enet_host_create() now requires the channel limit to be specified as
|
||||
a parameter
|
||||
* enet_host_connect() now accepts a data parameter which is supplied
|
||||
to the receiving receiving host in the event data field for a connect event
|
||||
* added an adaptive order-2 PPM range coder as a built-in compressor option
|
||||
which can be set with enet_host_compress_with_range_coder()
|
||||
* added support for packet compression configurable with a callback
|
||||
* improved session number handling to not rely on the packet checksum
|
||||
field, saving 4 bytes per packet unless the checksum option is used
|
||||
* removed the dependence on the rand callback for session number handling
|
||||
|
||||
Caveats: This version is not protocol compatible with the 1.2 series or
|
||||
earlier. The enet_host_connect and enet_host_create API functions require
|
||||
supplying additional parameters.
|
||||
|
||||
ENet 1.2.5 (June 28, 2011):
|
||||
|
||||
* fixed bug with simultaneous disconnects not dispatching events
|
||||
|
||||
ENet 1.2.4 (May 31, 2011):
|
||||
|
||||
* fixed regression in unreliable packet queuing
|
||||
* added check against received port to limit some forms of IP-spoofing
|
||||
|
||||
ENet 1.2.3 (February 10, 2011):
|
||||
|
||||
* fixed bug in tracking reliable data in transit
|
||||
|
||||
ENet 1.2.2 (June 5, 2010):
|
||||
|
||||
* checksum functionality is now enabled by setting a checksum callback
|
||||
inside ENetHost instead of being a configure script option
|
||||
* added totalSentData, totalSentPackets, totalReceivedData, and
|
||||
totalReceivedPackets counters inside ENetHost for getting usage
|
||||
statistics
|
||||
* added enet_host_channel_limit() for limiting the maximum number of
|
||||
channels allowed by connected peers
|
||||
* now uses dispatch queues for event dispatch rather than potentially
|
||||
unscalable array walking
|
||||
* added no_memory callback that is called when a malloc attempt fails,
|
||||
such that if no_memory returns rather than aborts (the default behavior),
|
||||
then the error is propagated to the return value of the API calls
|
||||
* now uses packed attribute for protocol structures on platforms with
|
||||
strange alignment rules
|
||||
* improved autoconf build system contributed by Nathan Brink allowing
|
||||
for easier building as a shared library
|
||||
|
||||
Caveats: If you were using the compile-time option that enabled checksums,
|
||||
make sure to set the checksum callback inside ENetHost to enet_crc32 to
|
||||
regain the old behavior. The ENetCallbacks structure has added new fields,
|
||||
so make sure to clear the structure to zero before use if
|
||||
using enet_initialize_with_callbacks().
|
||||
|
||||
ENet 1.2.1 (November 12, 2009):
|
||||
|
||||
* fixed bug that could cause disconnect events to be dropped
|
||||
* added thin wrapper around select() for portable usage
|
||||
* added ENET_SOCKOPT_REUSEADDR socket option
|
||||
* factored enet_socket_bind()/enet_socket_listen() out of enet_socket_create()
|
||||
* added contributed Code::Blocks build file
|
||||
|
||||
ENet 1.2 (February 12, 2008):
|
||||
|
||||
* fixed bug in VERIFY_CONNECT acknowledgement that could cause connect
|
||||
attempts to occasionally timeout
|
||||
* fixed acknowledgements to check both the outgoing and sent queues
|
||||
when removing acknowledged packets
|
||||
* fixed accidental bit rot in the MSVC project file
|
||||
* revised sequence number overflow handling to address some possible
|
||||
disconnect bugs
|
||||
* added enet_host_check_events() for getting only local queued events
|
||||
* factored out socket option setting into enet_socket_set_option() so
|
||||
that socket options are now set separately from enet_socket_create()
|
||||
|
||||
Caveats: While this release is superficially protocol compatible with 1.1,
|
||||
differences in the sequence number overflow handling can potentially cause
|
||||
random disconnects.
|
||||
|
||||
ENet 1.1 (June 6, 2007):
|
||||
|
||||
* optional CRC32 just in case someone needs a stronger checksum than UDP
|
||||
provides (--enable-crc32 configure option)
|
||||
* the size of packet headers are half the size they used to be (so less
|
||||
overhead when sending small packets)
|
||||
* enet_peer_disconnect_later() that waits till all queued outgoing
|
||||
packets get sent before issuing an actual disconnect
|
||||
* freeCallback field in individual packets for notification of when a
|
||||
packet is about to be freed
|
||||
* ENET_PACKET_FLAG_NO_ALLOCATE for supplying pre-allocated data to a
|
||||
packet (can be used in concert with freeCallback to support some custom
|
||||
allocation schemes that the normal memory allocation callbacks would
|
||||
normally not allow)
|
||||
* enet_address_get_host_ip() for printing address numbers
|
||||
* promoted the enet_socket_*() functions to be part of the API now
|
||||
* a few stability/crash fixes
|
||||
|
||||
|
||||
+2303
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,191 @@
|
||||
<doxygenlayout version="1.0">
|
||||
<!-- Generated by doxygen 1.8.6 -->
|
||||
<!-- Navigation index tabs for HTML output -->
|
||||
<navindex>
|
||||
<tab type="mainpage" visible="yes" title="Home"/>
|
||||
<tab type="user" visible="yes" title="Features" url="@ref Features" />
|
||||
<tab type="user" visible="yes" title="Downloads" url="@ref Downloads" />
|
||||
<tab type="user" visible="yes" title="Installation" url="@ref Installation" />
|
||||
<tab type="user" visible="yes" title="Tutorial" url="@ref Tutorial" />
|
||||
<tab type="user" visible="yes" title="Mailing List" url="@ref MailingList" />
|
||||
<tab type="user" visible="yes" title="IRC Channel" url="@ref IRCChannel" />
|
||||
<tab type="user" visible="yes" title="FAQ" url="@ref FAQ" />
|
||||
<tab type="user" visible="yes" title="License" url="@ref License" />
|
||||
<tab type="usergroup" visible="yes" title="Documentation" briefdescription="Documentation">
|
||||
<tab type="modules" visible="yes" title="Functions" intro=""/>
|
||||
<tab type="classlist" visible="yes" title="Data Structures" intro=""/>
|
||||
<tab type="filelist" visible="yes" title="Files" intro=""/>
|
||||
<tab type="globals" visible="yes" title="" intro=""/>
|
||||
</tab>
|
||||
</navindex>
|
||||
|
||||
<!-- Layout definition for a class page -->
|
||||
<class>
|
||||
<briefdescription visible="yes"/>
|
||||
<includes visible="$SHOW_INCLUDE_FILES"/>
|
||||
<inheritancegraph visible="$CLASS_GRAPH"/>
|
||||
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
|
||||
<memberdecl>
|
||||
<nestedclasses visible="yes" title=""/>
|
||||
<publictypes title=""/>
|
||||
<services title=""/>
|
||||
<interfaces title=""/>
|
||||
<publicslots title=""/>
|
||||
<signals title=""/>
|
||||
<publicmethods title=""/>
|
||||
<publicstaticmethods title=""/>
|
||||
<publicattributes title=""/>
|
||||
<publicstaticattributes title=""/>
|
||||
<protectedtypes title=""/>
|
||||
<protectedslots title=""/>
|
||||
<protectedmethods title=""/>
|
||||
<protectedstaticmethods title=""/>
|
||||
<protectedattributes title=""/>
|
||||
<protectedstaticattributes title=""/>
|
||||
<packagetypes title=""/>
|
||||
<packagemethods title=""/>
|
||||
<packagestaticmethods title=""/>
|
||||
<packageattributes title=""/>
|
||||
<packagestaticattributes title=""/>
|
||||
<properties title=""/>
|
||||
<events title=""/>
|
||||
<privatetypes title=""/>
|
||||
<privateslots title=""/>
|
||||
<privatemethods title=""/>
|
||||
<privatestaticmethods title=""/>
|
||||
<privateattributes title=""/>
|
||||
<privatestaticattributes title=""/>
|
||||
<friends title=""/>
|
||||
<related title="" subtitle=""/>
|
||||
<membergroups visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title=""/>
|
||||
<memberdef>
|
||||
<inlineclasses title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<services title=""/>
|
||||
<interfaces title=""/>
|
||||
<constructors title=""/>
|
||||
<functions title=""/>
|
||||
<related title=""/>
|
||||
<variables title=""/>
|
||||
<properties title=""/>
|
||||
<events title=""/>
|
||||
</memberdef>
|
||||
<allmemberslink visible="yes"/>
|
||||
<usedfiles visible="$SHOW_USED_FILES"/>
|
||||
<authorsection visible="yes"/>
|
||||
</class>
|
||||
|
||||
<!-- Layout definition for a namespace page -->
|
||||
<namespace>
|
||||
<briefdescription visible="yes"/>
|
||||
<memberdecl>
|
||||
<nestednamespaces visible="yes" title=""/>
|
||||
<constantgroups visible="yes" title=""/>
|
||||
<classes visible="yes" title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
<membergroups visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title=""/>
|
||||
<memberdef>
|
||||
<inlineclasses title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
</memberdef>
|
||||
<authorsection visible="yes"/>
|
||||
</namespace>
|
||||
|
||||
<!-- Layout definition for a file page -->
|
||||
<file>
|
||||
<briefdescription visible="yes"/>
|
||||
<includes visible="$SHOW_INCLUDE_FILES"/>
|
||||
<includegraph visible="$INCLUDE_GRAPH"/>
|
||||
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
|
||||
<sourcelink visible="yes"/>
|
||||
<memberdecl>
|
||||
<classes visible="yes" title=""/>
|
||||
<namespaces visible="yes" title=""/>
|
||||
<constantgroups visible="yes" title=""/>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
<membergroups visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title=""/>
|
||||
<memberdef>
|
||||
<inlineclasses title=""/>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
</memberdef>
|
||||
<authorsection/>
|
||||
</file>
|
||||
|
||||
<!-- Layout definition for a group page -->
|
||||
<group>
|
||||
<briefdescription visible="yes"/>
|
||||
<groupgraph visible="$GROUP_GRAPHS"/>
|
||||
<memberdecl>
|
||||
<nestedgroups visible="yes" title=""/>
|
||||
<dirs visible="yes" title=""/>
|
||||
<files visible="yes" title=""/>
|
||||
<namespaces visible="yes" title=""/>
|
||||
<classes visible="yes" title=""/>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<enumvalues title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
<signals title=""/>
|
||||
<publicslots title=""/>
|
||||
<protectedslots title=""/>
|
||||
<privateslots title=""/>
|
||||
<events title=""/>
|
||||
<properties title=""/>
|
||||
<friends title=""/>
|
||||
<membergroups visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title=""/>
|
||||
<memberdef>
|
||||
<pagedocs/>
|
||||
<inlineclasses title=""/>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<enumvalues title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
<signals title=""/>
|
||||
<publicslots title=""/>
|
||||
<protectedslots title=""/>
|
||||
<privateslots title=""/>
|
||||
<events title=""/>
|
||||
<properties title=""/>
|
||||
<friends title=""/>
|
||||
</memberdef>
|
||||
<authorsection visible="yes"/>
|
||||
</group>
|
||||
|
||||
<!-- Layout definition for a directory page -->
|
||||
<directory>
|
||||
<briefdescription visible="yes"/>
|
||||
<directorygraph visible="yes"/>
|
||||
<memberdecl>
|
||||
<dirs visible="yes"/>
|
||||
<files visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title=""/>
|
||||
</directory>
|
||||
</doxygenlayout>
|
||||
@@ -0,0 +1,7 @@
|
||||
Copyright (c) 2002-2024 Lee Salzman
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,22 @@
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
nodist_pkgconfig_DATA = libenet.pc
|
||||
|
||||
enetincludedir=$(includedir)/enet
|
||||
enetinclude_HEADERS = \
|
||||
include/enet/callbacks.h \
|
||||
include/enet/enet.h \
|
||||
include/enet/list.h \
|
||||
include/enet/protocol.h \
|
||||
include/enet/time.h \
|
||||
include/enet/types.h \
|
||||
include/enet/unix.h \
|
||||
include/enet/utility.h \
|
||||
include/enet/win32.h
|
||||
|
||||
lib_LTLIBRARIES = libenet.la
|
||||
libenet_la_SOURCES = callbacks.c compress.c host.c list.c packet.c peer.c protocol.c unix.c win32.c
|
||||
# see info '(libtool) Updating version info' before making a release
|
||||
libenet_la_LDFLAGS = $(AM_LDFLAGS) -version-info 7:6:0
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||
|
||||
ACLOCAL_AMFLAGS = -Im4
|
||||
@@ -0,0 +1,15 @@
|
||||
Please visit the ENet homepage at http://sauerbraten.org/enet/ for installation
|
||||
and usage instructions.
|
||||
|
||||
If you obtained this package from github, the quick description on how to build
|
||||
is:
|
||||
|
||||
# Generate the build system.
|
||||
|
||||
autoreconf -vfi
|
||||
|
||||
# Compile and install the library.
|
||||
|
||||
./configure && make && make install
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
@file callbacks.c
|
||||
@brief ENet callback functions
|
||||
*/
|
||||
#define ENET_BUILDING_LIB 1
|
||||
#include "enet/enet.h"
|
||||
|
||||
static ENetCallbacks callbacks = { malloc, free, abort };
|
||||
|
||||
int
|
||||
enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits)
|
||||
{
|
||||
if (version < ENET_VERSION_CREATE (1, 3, 0))
|
||||
return -1;
|
||||
|
||||
if (inits -> malloc != NULL || inits -> free != NULL)
|
||||
{
|
||||
if (inits -> malloc == NULL || inits -> free == NULL)
|
||||
return -1;
|
||||
|
||||
callbacks.malloc = inits -> malloc;
|
||||
callbacks.free = inits -> free;
|
||||
}
|
||||
|
||||
if (inits -> no_memory != NULL)
|
||||
callbacks.no_memory = inits -> no_memory;
|
||||
|
||||
return enet_initialize ();
|
||||
}
|
||||
|
||||
ENetVersion
|
||||
enet_linked_version (void)
|
||||
{
|
||||
return ENET_VERSION;
|
||||
}
|
||||
|
||||
void *
|
||||
enet_malloc (size_t size)
|
||||
{
|
||||
void * memory = callbacks.malloc (size);
|
||||
|
||||
if (memory == NULL)
|
||||
callbacks.no_memory ();
|
||||
|
||||
return memory;
|
||||
}
|
||||
|
||||
void
|
||||
enet_free (void * memory)
|
||||
{
|
||||
callbacks.free (memory);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,654 @@
|
||||
/**
|
||||
@file compress.c
|
||||
@brief An adaptive order-2 PPM range coder
|
||||
*/
|
||||
#define ENET_BUILDING_LIB 1
|
||||
#include <string.h>
|
||||
#include "enet/enet.h"
|
||||
|
||||
typedef struct _ENetSymbol
|
||||
{
|
||||
/* binary indexed tree of symbols */
|
||||
enet_uint8 value;
|
||||
enet_uint8 count;
|
||||
enet_uint16 under;
|
||||
enet_uint16 left, right;
|
||||
|
||||
/* context defined by this symbol */
|
||||
enet_uint16 symbols;
|
||||
enet_uint16 escapes;
|
||||
enet_uint16 total;
|
||||
enet_uint16 parent;
|
||||
} ENetSymbol;
|
||||
|
||||
/* adaptation constants tuned aggressively for small packet sizes rather than large file compression */
|
||||
enum
|
||||
{
|
||||
ENET_RANGE_CODER_TOP = 1<<24,
|
||||
ENET_RANGE_CODER_BOTTOM = 1<<16,
|
||||
|
||||
ENET_CONTEXT_SYMBOL_DELTA = 3,
|
||||
ENET_CONTEXT_SYMBOL_MINIMUM = 1,
|
||||
ENET_CONTEXT_ESCAPE_MINIMUM = 1,
|
||||
|
||||
ENET_SUBCONTEXT_ORDER = 2,
|
||||
ENET_SUBCONTEXT_SYMBOL_DELTA = 2,
|
||||
ENET_SUBCONTEXT_ESCAPE_DELTA = 5
|
||||
};
|
||||
|
||||
/* context exclusion roughly halves compression speed, so disable for now */
|
||||
#undef ENET_CONTEXT_EXCLUSION
|
||||
|
||||
typedef struct _ENetRangeCoder
|
||||
{
|
||||
/* only allocate enough symbols for reasonable MTUs, would need to be larger for large file compression */
|
||||
ENetSymbol symbols[4096];
|
||||
} ENetRangeCoder;
|
||||
|
||||
void *
|
||||
enet_range_coder_create (void)
|
||||
{
|
||||
ENetRangeCoder * rangeCoder = (ENetRangeCoder *) enet_malloc (sizeof (ENetRangeCoder));
|
||||
if (rangeCoder == NULL)
|
||||
return NULL;
|
||||
|
||||
return rangeCoder;
|
||||
}
|
||||
|
||||
void
|
||||
enet_range_coder_destroy (void * context)
|
||||
{
|
||||
ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context;
|
||||
if (rangeCoder == NULL)
|
||||
return;
|
||||
|
||||
enet_free (rangeCoder);
|
||||
}
|
||||
|
||||
#define ENET_SYMBOL_CREATE(symbol, value_, count_) \
|
||||
{ \
|
||||
symbol = & rangeCoder -> symbols [nextSymbol ++]; \
|
||||
symbol -> value = value_; \
|
||||
symbol -> count = count_; \
|
||||
symbol -> under = count_; \
|
||||
symbol -> left = 0; \
|
||||
symbol -> right = 0; \
|
||||
symbol -> symbols = 0; \
|
||||
symbol -> escapes = 0; \
|
||||
symbol -> total = 0; \
|
||||
symbol -> parent = 0; \
|
||||
}
|
||||
|
||||
#define ENET_CONTEXT_CREATE(context, escapes_, minimum) \
|
||||
{ \
|
||||
ENET_SYMBOL_CREATE (context, 0, 0); \
|
||||
(context) -> escapes = escapes_; \
|
||||
(context) -> total = escapes_ + 256*minimum; \
|
||||
(context) -> symbols = 0; \
|
||||
}
|
||||
|
||||
static enet_uint16
|
||||
enet_symbol_rescale (ENetSymbol * symbol)
|
||||
{
|
||||
enet_uint16 total = 0;
|
||||
for (;;)
|
||||
{
|
||||
symbol -> count -= symbol->count >> 1;
|
||||
symbol -> under = symbol -> count;
|
||||
if (symbol -> left)
|
||||
symbol -> under += enet_symbol_rescale (symbol + symbol -> left);
|
||||
total += symbol -> under;
|
||||
if (! symbol -> right) break;
|
||||
symbol += symbol -> right;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
#define ENET_CONTEXT_RESCALE(context, minimum) \
|
||||
{ \
|
||||
(context) -> total = (context) -> symbols ? enet_symbol_rescale ((context) + (context) -> symbols) : 0; \
|
||||
(context) -> escapes -= (context) -> escapes >> 1; \
|
||||
(context) -> total += (context) -> escapes + 256*minimum; \
|
||||
}
|
||||
|
||||
#define ENET_RANGE_CODER_OUTPUT(value) \
|
||||
{ \
|
||||
if (outData >= outEnd) \
|
||||
return 0; \
|
||||
* outData ++ = value; \
|
||||
}
|
||||
|
||||
#define ENET_RANGE_CODER_ENCODE(under, count, total) \
|
||||
{ \
|
||||
encodeRange /= (total); \
|
||||
encodeLow += (under) * encodeRange; \
|
||||
encodeRange *= (count); \
|
||||
for (;;) \
|
||||
{ \
|
||||
if((encodeLow ^ (encodeLow + encodeRange)) >= ENET_RANGE_CODER_TOP) \
|
||||
{ \
|
||||
if(encodeRange >= ENET_RANGE_CODER_BOTTOM) break; \
|
||||
encodeRange = -encodeLow & (ENET_RANGE_CODER_BOTTOM - 1); \
|
||||
} \
|
||||
ENET_RANGE_CODER_OUTPUT (encodeLow >> 24); \
|
||||
encodeRange <<= 8; \
|
||||
encodeLow <<= 8; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define ENET_RANGE_CODER_FLUSH \
|
||||
{ \
|
||||
while (encodeLow) \
|
||||
{ \
|
||||
ENET_RANGE_CODER_OUTPUT (encodeLow >> 24); \
|
||||
encodeLow <<= 8; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define ENET_RANGE_CODER_FREE_SYMBOLS \
|
||||
{ \
|
||||
if (nextSymbol >= sizeof (rangeCoder -> symbols) / sizeof (ENetSymbol) - ENET_SUBCONTEXT_ORDER ) \
|
||||
{ \
|
||||
nextSymbol = 0; \
|
||||
ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM); \
|
||||
predicted = 0; \
|
||||
order = 0; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define ENET_CONTEXT_ENCODE(context, symbol_, value_, under_, count_, update, minimum) \
|
||||
{ \
|
||||
under_ = value*minimum; \
|
||||
count_ = minimum; \
|
||||
if (! (context) -> symbols) \
|
||||
{ \
|
||||
ENET_SYMBOL_CREATE (symbol_, value_, update); \
|
||||
(context) -> symbols = symbol_ - (context); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
ENetSymbol * node = (context) + (context) -> symbols; \
|
||||
for (;;) \
|
||||
{ \
|
||||
if (value_ < node -> value) \
|
||||
{ \
|
||||
node -> under += update; \
|
||||
if (node -> left) { node += node -> left; continue; } \
|
||||
ENET_SYMBOL_CREATE (symbol_, value_, update); \
|
||||
node -> left = symbol_ - node; \
|
||||
} \
|
||||
else \
|
||||
if (value_ > node -> value) \
|
||||
{ \
|
||||
under_ += node -> under; \
|
||||
if (node -> right) { node += node -> right; continue; } \
|
||||
ENET_SYMBOL_CREATE (symbol_, value_, update); \
|
||||
node -> right = symbol_ - node; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
count_ += node -> count; \
|
||||
under_ += node -> under - node -> count; \
|
||||
node -> under += update; \
|
||||
node -> count += update; \
|
||||
symbol_ = node; \
|
||||
} \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#ifdef ENET_CONTEXT_EXCLUSION
|
||||
static const ENetSymbol emptyContext = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
#define ENET_CONTEXT_WALK(context, body) \
|
||||
{ \
|
||||
const ENetSymbol * node = (context) + (context) -> symbols; \
|
||||
const ENetSymbol * stack [256]; \
|
||||
size_t stackSize = 0; \
|
||||
while (node -> left) \
|
||||
{ \
|
||||
stack [stackSize ++] = node; \
|
||||
node += node -> left; \
|
||||
} \
|
||||
for (;;) \
|
||||
{ \
|
||||
body; \
|
||||
if (node -> right) \
|
||||
{ \
|
||||
node += node -> right; \
|
||||
while (node -> left) \
|
||||
{ \
|
||||
stack [stackSize ++] = node; \
|
||||
node += node -> left; \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
if (stackSize <= 0) \
|
||||
break; \
|
||||
else \
|
||||
node = stack [-- stackSize]; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define ENET_CONTEXT_ENCODE_EXCLUDE(context, value_, under, total, minimum) \
|
||||
ENET_CONTEXT_WALK(context, { \
|
||||
if (node -> value != value_) \
|
||||
{ \
|
||||
enet_uint16 parentCount = rangeCoder -> symbols [node -> parent].count + minimum; \
|
||||
if (node -> value < value_) \
|
||||
under -= parentCount; \
|
||||
total -= parentCount; \
|
||||
} \
|
||||
})
|
||||
#endif
|
||||
|
||||
size_t
|
||||
enet_range_coder_compress (void * context, const ENetBuffer * inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 * outData, size_t outLimit)
|
||||
{
|
||||
ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context;
|
||||
enet_uint8 * outStart = outData, * outEnd = & outData [outLimit];
|
||||
const enet_uint8 * inData, * inEnd;
|
||||
enet_uint32 encodeLow = 0, encodeRange = ~0;
|
||||
ENetSymbol * root;
|
||||
enet_uint16 predicted = 0;
|
||||
size_t order = 0, nextSymbol = 0;
|
||||
|
||||
if (rangeCoder == NULL || inBufferCount <= 0 || inLimit <= 0)
|
||||
return 0;
|
||||
|
||||
inData = (const enet_uint8 *) inBuffers -> data;
|
||||
inEnd = & inData [inBuffers -> dataLength];
|
||||
inBuffers ++;
|
||||
inBufferCount --;
|
||||
|
||||
ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
ENetSymbol * subcontext, * symbol;
|
||||
#ifdef ENET_CONTEXT_EXCLUSION
|
||||
const ENetSymbol * childContext = & emptyContext;
|
||||
#endif
|
||||
enet_uint8 value;
|
||||
enet_uint16 count, under, * parent = & predicted, total;
|
||||
if (inData >= inEnd)
|
||||
{
|
||||
if (inBufferCount <= 0)
|
||||
break;
|
||||
inData = (const enet_uint8 *) inBuffers -> data;
|
||||
inEnd = & inData [inBuffers -> dataLength];
|
||||
inBuffers ++;
|
||||
inBufferCount --;
|
||||
}
|
||||
value = * inData ++;
|
||||
|
||||
for (subcontext = & rangeCoder -> symbols [predicted];
|
||||
subcontext != root;
|
||||
#ifdef ENET_CONTEXT_EXCLUSION
|
||||
childContext = subcontext,
|
||||
#endif
|
||||
subcontext = & rangeCoder -> symbols [subcontext -> parent])
|
||||
{
|
||||
ENET_CONTEXT_ENCODE (subcontext, symbol, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0);
|
||||
* parent = symbol - rangeCoder -> symbols;
|
||||
parent = & symbol -> parent;
|
||||
total = subcontext -> total;
|
||||
#ifdef ENET_CONTEXT_EXCLUSION
|
||||
if (childContext -> total > ENET_SUBCONTEXT_SYMBOL_DELTA + ENET_SUBCONTEXT_ESCAPE_DELTA)
|
||||
ENET_CONTEXT_ENCODE_EXCLUDE (childContext, value, under, total, 0);
|
||||
#endif
|
||||
if (count > 0)
|
||||
{
|
||||
ENET_RANGE_CODER_ENCODE (subcontext -> escapes + under, count, total);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (subcontext -> escapes > 0 && subcontext -> escapes < total)
|
||||
ENET_RANGE_CODER_ENCODE (0, subcontext -> escapes, total);
|
||||
subcontext -> escapes += ENET_SUBCONTEXT_ESCAPE_DELTA;
|
||||
subcontext -> total += ENET_SUBCONTEXT_ESCAPE_DELTA;
|
||||
}
|
||||
subcontext -> total += ENET_SUBCONTEXT_SYMBOL_DELTA;
|
||||
if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || subcontext -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
|
||||
ENET_CONTEXT_RESCALE (subcontext, 0);
|
||||
if (count > 0) goto nextInput;
|
||||
}
|
||||
|
||||
ENET_CONTEXT_ENCODE (root, symbol, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM);
|
||||
* parent = symbol - rangeCoder -> symbols;
|
||||
parent = & symbol -> parent;
|
||||
total = root -> total;
|
||||
#ifdef ENET_CONTEXT_EXCLUSION
|
||||
if (childContext -> total > ENET_SUBCONTEXT_SYMBOL_DELTA + ENET_SUBCONTEXT_ESCAPE_DELTA)
|
||||
ENET_CONTEXT_ENCODE_EXCLUDE (childContext, value, under, total, ENET_CONTEXT_SYMBOL_MINIMUM);
|
||||
#endif
|
||||
ENET_RANGE_CODER_ENCODE (root -> escapes + under, count, total);
|
||||
root -> total += ENET_CONTEXT_SYMBOL_DELTA;
|
||||
if (count > 0xFF - 2*ENET_CONTEXT_SYMBOL_DELTA + ENET_CONTEXT_SYMBOL_MINIMUM || root -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
|
||||
ENET_CONTEXT_RESCALE (root, ENET_CONTEXT_SYMBOL_MINIMUM);
|
||||
|
||||
nextInput:
|
||||
if (order >= ENET_SUBCONTEXT_ORDER)
|
||||
predicted = rangeCoder -> symbols [predicted].parent;
|
||||
else
|
||||
order ++;
|
||||
ENET_RANGE_CODER_FREE_SYMBOLS;
|
||||
}
|
||||
|
||||
ENET_RANGE_CODER_FLUSH;
|
||||
|
||||
return (size_t) (outData - outStart);
|
||||
}
|
||||
|
||||
#define ENET_RANGE_CODER_SEED \
|
||||
{ \
|
||||
if (inData < inEnd) decodeCode |= * inData ++ << 24; \
|
||||
if (inData < inEnd) decodeCode |= * inData ++ << 16; \
|
||||
if (inData < inEnd) decodeCode |= * inData ++ << 8; \
|
||||
if (inData < inEnd) decodeCode |= * inData ++; \
|
||||
}
|
||||
|
||||
#define ENET_RANGE_CODER_READ(total) ((decodeCode - decodeLow) / (decodeRange /= (total)))
|
||||
|
||||
#define ENET_RANGE_CODER_DECODE(under, count, total) \
|
||||
{ \
|
||||
decodeLow += (under) * decodeRange; \
|
||||
decodeRange *= (count); \
|
||||
for (;;) \
|
||||
{ \
|
||||
if((decodeLow ^ (decodeLow + decodeRange)) >= ENET_RANGE_CODER_TOP) \
|
||||
{ \
|
||||
if(decodeRange >= ENET_RANGE_CODER_BOTTOM) break; \
|
||||
decodeRange = -decodeLow & (ENET_RANGE_CODER_BOTTOM - 1); \
|
||||
} \
|
||||
decodeCode <<= 8; \
|
||||
if (inData < inEnd) \
|
||||
decodeCode |= * inData ++; \
|
||||
decodeRange <<= 8; \
|
||||
decodeLow <<= 8; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define ENET_CONTEXT_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, createRoot, visitNode, createRight, createLeft) \
|
||||
{ \
|
||||
under_ = 0; \
|
||||
count_ = minimum; \
|
||||
if (! (context) -> symbols) \
|
||||
{ \
|
||||
createRoot; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
ENetSymbol * node = (context) + (context) -> symbols; \
|
||||
for (;;) \
|
||||
{ \
|
||||
enet_uint16 after = under_ + node -> under + (node -> value + 1)*minimum, before = node -> count + minimum; \
|
||||
visitNode; \
|
||||
if (code >= after) \
|
||||
{ \
|
||||
under_ += node -> under; \
|
||||
if (node -> right) { node += node -> right; continue; } \
|
||||
createRight; \
|
||||
} \
|
||||
else \
|
||||
if (code < after - before) \
|
||||
{ \
|
||||
node -> under += update; \
|
||||
if (node -> left) { node += node -> left; continue; } \
|
||||
createLeft; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
value_ = node -> value; \
|
||||
count_ += node -> count; \
|
||||
under_ = after - before; \
|
||||
node -> under += update; \
|
||||
node -> count += update; \
|
||||
symbol_ = node; \
|
||||
} \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define ENET_CONTEXT_TRY_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, exclude) \
|
||||
ENET_CONTEXT_DECODE (context, symbol_, code, value_, under_, count_, update, minimum, return 0, exclude (node -> value, after, before), return 0, return 0)
|
||||
|
||||
#define ENET_CONTEXT_ROOT_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, exclude) \
|
||||
ENET_CONTEXT_DECODE (context, symbol_, code, value_, under_, count_, update, minimum, \
|
||||
{ \
|
||||
value_ = code / minimum; \
|
||||
under_ = code - code%minimum; \
|
||||
ENET_SYMBOL_CREATE (symbol_, value_, update); \
|
||||
(context) -> symbols = symbol_ - (context); \
|
||||
}, \
|
||||
exclude (node -> value, after, before), \
|
||||
{ \
|
||||
value_ = node->value + 1 + (code - after)/minimum; \
|
||||
under_ = code - (code - after)%minimum; \
|
||||
ENET_SYMBOL_CREATE (symbol_, value_, update); \
|
||||
node -> right = symbol_ - node; \
|
||||
}, \
|
||||
{ \
|
||||
value_ = node->value - 1 - (after - before - code - 1)/minimum; \
|
||||
under_ = code - (after - before - code - 1)%minimum; \
|
||||
ENET_SYMBOL_CREATE (symbol_, value_, update); \
|
||||
node -> left = symbol_ - node; \
|
||||
}) \
|
||||
|
||||
#ifdef ENET_CONTEXT_EXCLUSION
|
||||
typedef struct _ENetExclude
|
||||
{
|
||||
enet_uint8 value;
|
||||
enet_uint16 under;
|
||||
} ENetExclude;
|
||||
|
||||
#define ENET_CONTEXT_DECODE_EXCLUDE(context, total, minimum) \
|
||||
{ \
|
||||
enet_uint16 under = 0; \
|
||||
nextExclude = excludes; \
|
||||
ENET_CONTEXT_WALK (context, { \
|
||||
under += rangeCoder -> symbols [node -> parent].count + minimum; \
|
||||
nextExclude -> value = node -> value; \
|
||||
nextExclude -> under = under; \
|
||||
nextExclude ++; \
|
||||
}); \
|
||||
total -= under; \
|
||||
}
|
||||
|
||||
#define ENET_CONTEXT_EXCLUDED(value_, after, before) \
|
||||
{ \
|
||||
size_t low = 0, high = nextExclude - excludes; \
|
||||
for(;;) \
|
||||
{ \
|
||||
size_t mid = (low + high) >> 1; \
|
||||
const ENetExclude * exclude = & excludes [mid]; \
|
||||
if (value_ < exclude -> value) \
|
||||
{ \
|
||||
if (low + 1 < high) \
|
||||
{ \
|
||||
high = mid; \
|
||||
continue; \
|
||||
} \
|
||||
if (exclude > excludes) \
|
||||
after -= exclude [-1].under; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
if (value_ > exclude -> value) \
|
||||
{ \
|
||||
if (low + 1 < high) \
|
||||
{ \
|
||||
low = mid; \
|
||||
continue; \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
before = 0; \
|
||||
after -= exclude -> under; \
|
||||
} \
|
||||
break; \
|
||||
} \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define ENET_CONTEXT_NOT_EXCLUDED(value_, after, before)
|
||||
|
||||
size_t
|
||||
enet_range_coder_decompress (void * context, const enet_uint8 * inData, size_t inLimit, enet_uint8 * outData, size_t outLimit)
|
||||
{
|
||||
ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context;
|
||||
enet_uint8 * outStart = outData, * outEnd = & outData [outLimit];
|
||||
const enet_uint8 * inEnd = & inData [inLimit];
|
||||
enet_uint32 decodeLow = 0, decodeCode = 0, decodeRange = ~0;
|
||||
ENetSymbol * root;
|
||||
enet_uint16 predicted = 0;
|
||||
size_t order = 0, nextSymbol = 0;
|
||||
#ifdef ENET_CONTEXT_EXCLUSION
|
||||
ENetExclude excludes [256];
|
||||
ENetExclude * nextExclude = excludes;
|
||||
#endif
|
||||
|
||||
if (rangeCoder == NULL || inLimit <= 0)
|
||||
return 0;
|
||||
|
||||
ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM);
|
||||
|
||||
ENET_RANGE_CODER_SEED;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
ENetSymbol * subcontext, * symbol, * patch;
|
||||
#ifdef ENET_CONTEXT_EXCLUSION
|
||||
const ENetSymbol * childContext = & emptyContext;
|
||||
#endif
|
||||
enet_uint8 value = 0;
|
||||
enet_uint16 code, under, count, bottom, * parent = & predicted, total;
|
||||
|
||||
for (subcontext = & rangeCoder -> symbols [predicted];
|
||||
subcontext != root;
|
||||
#ifdef ENET_CONTEXT_EXCLUSION
|
||||
childContext = subcontext,
|
||||
#endif
|
||||
subcontext = & rangeCoder -> symbols [subcontext -> parent])
|
||||
{
|
||||
if (subcontext -> escapes <= 0)
|
||||
continue;
|
||||
total = subcontext -> total;
|
||||
#ifdef ENET_CONTEXT_EXCLUSION
|
||||
if (childContext -> total > 0)
|
||||
ENET_CONTEXT_DECODE_EXCLUDE (childContext, total, 0);
|
||||
#endif
|
||||
if (subcontext -> escapes >= total)
|
||||
continue;
|
||||
code = ENET_RANGE_CODER_READ (total);
|
||||
if (code < subcontext -> escapes)
|
||||
{
|
||||
ENET_RANGE_CODER_DECODE (0, subcontext -> escapes, total);
|
||||
continue;
|
||||
}
|
||||
code -= subcontext -> escapes;
|
||||
#ifdef ENET_CONTEXT_EXCLUSION
|
||||
if (childContext -> total > 0)
|
||||
{
|
||||
ENET_CONTEXT_TRY_DECODE (subcontext, symbol, code, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0, ENET_CONTEXT_EXCLUDED);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ENET_CONTEXT_TRY_DECODE (subcontext, symbol, code, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0, ENET_CONTEXT_NOT_EXCLUDED);
|
||||
}
|
||||
bottom = symbol - rangeCoder -> symbols;
|
||||
ENET_RANGE_CODER_DECODE (subcontext -> escapes + under, count, total);
|
||||
subcontext -> total += ENET_SUBCONTEXT_SYMBOL_DELTA;
|
||||
if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || subcontext -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
|
||||
ENET_CONTEXT_RESCALE (subcontext, 0);
|
||||
goto patchContexts;
|
||||
}
|
||||
|
||||
total = root -> total;
|
||||
#ifdef ENET_CONTEXT_EXCLUSION
|
||||
if (childContext -> total > 0)
|
||||
ENET_CONTEXT_DECODE_EXCLUDE (childContext, total, ENET_CONTEXT_SYMBOL_MINIMUM);
|
||||
#endif
|
||||
code = ENET_RANGE_CODER_READ (total);
|
||||
if (code < root -> escapes)
|
||||
{
|
||||
ENET_RANGE_CODER_DECODE (0, root -> escapes, total);
|
||||
break;
|
||||
}
|
||||
code -= root -> escapes;
|
||||
#ifdef ENET_CONTEXT_EXCLUSION
|
||||
if (childContext -> total > 0)
|
||||
{
|
||||
ENET_CONTEXT_ROOT_DECODE (root, symbol, code, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM, ENET_CONTEXT_EXCLUDED);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ENET_CONTEXT_ROOT_DECODE (root, symbol, code, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM, ENET_CONTEXT_NOT_EXCLUDED);
|
||||
}
|
||||
bottom = symbol - rangeCoder -> symbols;
|
||||
ENET_RANGE_CODER_DECODE (root -> escapes + under, count, total);
|
||||
root -> total += ENET_CONTEXT_SYMBOL_DELTA;
|
||||
if (count > 0xFF - 2*ENET_CONTEXT_SYMBOL_DELTA + ENET_CONTEXT_SYMBOL_MINIMUM || root -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
|
||||
ENET_CONTEXT_RESCALE (root, ENET_CONTEXT_SYMBOL_MINIMUM);
|
||||
|
||||
patchContexts:
|
||||
for (patch = & rangeCoder -> symbols [predicted];
|
||||
patch != subcontext;
|
||||
patch = & rangeCoder -> symbols [patch -> parent])
|
||||
{
|
||||
ENET_CONTEXT_ENCODE (patch, symbol, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0);
|
||||
* parent = symbol - rangeCoder -> symbols;
|
||||
parent = & symbol -> parent;
|
||||
if (count <= 0)
|
||||
{
|
||||
patch -> escapes += ENET_SUBCONTEXT_ESCAPE_DELTA;
|
||||
patch -> total += ENET_SUBCONTEXT_ESCAPE_DELTA;
|
||||
}
|
||||
patch -> total += ENET_SUBCONTEXT_SYMBOL_DELTA;
|
||||
if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || patch -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
|
||||
ENET_CONTEXT_RESCALE (patch, 0);
|
||||
}
|
||||
* parent = bottom;
|
||||
|
||||
ENET_RANGE_CODER_OUTPUT (value);
|
||||
|
||||
if (order >= ENET_SUBCONTEXT_ORDER)
|
||||
predicted = rangeCoder -> symbols [predicted].parent;
|
||||
else
|
||||
order ++;
|
||||
ENET_RANGE_CODER_FREE_SYMBOLS;
|
||||
}
|
||||
|
||||
return (size_t) (outData - outStart);
|
||||
}
|
||||
|
||||
/** @defgroup host ENet host functions
|
||||
@{
|
||||
*/
|
||||
|
||||
/** Sets the packet compressor the host should use to the default range coder.
|
||||
@param host host to enable the range coder for
|
||||
@returns 0 on success, < 0 on failure
|
||||
*/
|
||||
int
|
||||
enet_host_compress_with_range_coder (ENetHost * host)
|
||||
{
|
||||
ENetCompressor compressor;
|
||||
memset (& compressor, 0, sizeof (compressor));
|
||||
compressor.context = enet_range_coder_create();
|
||||
if (compressor.context == NULL)
|
||||
return -1;
|
||||
compressor.compress = enet_range_coder_compress;
|
||||
compressor.decompress = enet_range_coder_decompress;
|
||||
compressor.destroy = enet_range_coder_destroy;
|
||||
enet_host_compress (host, & compressor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
AC_INIT([libenet], [1.3.18])
|
||||
AC_CONFIG_SRCDIR([include/enet/enet.h])
|
||||
AM_INIT_AUTOMAKE([foreign])
|
||||
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
AC_PROG_CC
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
AC_CHECK_FUNC(getaddrinfo, [AC_DEFINE(HAS_GETADDRINFO)])
|
||||
AC_CHECK_FUNC(getnameinfo, [AC_DEFINE(HAS_GETNAMEINFO)])
|
||||
AC_CHECK_FUNC(gethostbyaddr_r, [AC_DEFINE(HAS_GETHOSTBYADDR_R)])
|
||||
AC_CHECK_FUNC(gethostbyname_r, [AC_DEFINE(HAS_GETHOSTBYNAME_R)])
|
||||
AC_CHECK_FUNC(poll, [AC_DEFINE(HAS_POLL)])
|
||||
AC_CHECK_FUNC(fcntl, [AC_DEFINE(HAS_FCNTL)])
|
||||
AC_CHECK_FUNC(inet_pton, [AC_DEFINE(HAS_INET_PTON)])
|
||||
AC_CHECK_FUNC(inet_ntop, [AC_DEFINE(HAS_INET_NTOP)])
|
||||
AC_CHECK_DECLS(offsetof, [AC_DEFINE(HAS_OFFSETOF)], [], [#include <stddef.h>])
|
||||
|
||||
AC_CHECK_MEMBER(struct msghdr.msg_flags, [AC_DEFINE(HAS_MSGHDR_FLAGS)], , [#include <sys/socket.h>])
|
||||
|
||||
AC_CHECK_TYPE(socklen_t, [AC_DEFINE(HAS_SOCKLEN_T)], ,
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
)
|
||||
|
||||
AC_CONFIG_FILES([Makefile
|
||||
libenet.pc])
|
||||
AC_OUTPUT
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
@page FAQ Frequently Answered Questions
|
||||
|
||||
@section Q1 Is ENet thread-safe?
|
||||
|
||||
ENet does not use any significant global variables, the vast majority
|
||||
of state is encapsulated in the ENetHost structure. As such, as long
|
||||
as the application guards access to this structure, then ENet should
|
||||
operate fine in a multi-threaded environment.
|
||||
|
||||
@section Q2 Isn't ENet just re-inventing TCP?! What's the point?
|
||||
|
||||
In a perfect world, that would be true. But as many have found, using
|
||||
TCP either in lieu of or in conjunction with UDP can lead to all kinds
|
||||
of nightmares. TCP is a good, solid protocol, however it simply isn't
|
||||
up to the task of real-time games. Too much of TCP's implementation
|
||||
dictates a policy that isn't practical for games. If you want to use
|
||||
TCP, then do so -- this library is for people that either don't want
|
||||
to use TCP or have tried and ended up being discouraged with the
|
||||
performance.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
@page Features Features and Architecture
|
||||
|
||||
ENet evolved specifically as a UDP networking layer for the
|
||||
multiplayer first person shooter Cube. Cube necessitated low latency
|
||||
communication with data sent out very frequently, so TCP was an
|
||||
unsuitable choice due to its high latency and stream orientation. UDP,
|
||||
however, lacks many sometimes necessary features from TCP such as
|
||||
reliability, sequencing, unrestricted packet sizes, and connection
|
||||
management. So UDP by itself was not suitable as a network protocol
|
||||
either. No suitable freely available networking libraries existed at
|
||||
the time of ENet's creation to fill this niche.
|
||||
|
||||
UDP and TCP could have been used together in Cube to benefit somewhat
|
||||
from both of their features, however, the resulting combinations of
|
||||
protocols still leaves much to be desired. TCP lacks multiple streams
|
||||
of communication without resorting to opening many sockets and
|
||||
complicates delineation of packets due to its buffering behavior. UDP
|
||||
lacks sequencing, connection management, management of bandwidth
|
||||
resources, and imposes limitations on the size of packets. A
|
||||
significant investment is required to integrate these two protocols,
|
||||
and the end result is worse off in features and performance than the
|
||||
uniform protocol presented by ENet.
|
||||
|
||||
ENet thus attempts to address these issues and provide a single,
|
||||
uniform protocol layered over UDP to the developer with the best
|
||||
features of UDP and TCP as well as some useful features neither
|
||||
provide, with a much cleaner integration than any resulting from a
|
||||
mixture of UDP and TCP.
|
||||
|
||||
@section CM Connection Management
|
||||
|
||||
ENet provides a simple connection interface over which to communicate
|
||||
with a foreign host. The liveness of the connection is actively
|
||||
monitored by pinging the foreign host at frequent intervals, and also
|
||||
monitors the network conditions from the local host to the foreign
|
||||
host such as the mean round trip time and packet loss in this fashion.
|
||||
|
||||
@section Sequencing Sequencing
|
||||
|
||||
Rather than a single byte stream that complicates the delineation of
|
||||
packets, ENet presents connections as multiple, properly sequenced
|
||||
packet streams that simplify the transfer of various types of data.
|
||||
|
||||
ENet provides sequencing for all packets by assigning to each sent
|
||||
packet a sequence number that is incremented as packets are sent. ENet
|
||||
guarantees that no packet with a higher sequence number will be
|
||||
delivered before a packet with a lower sequence number, thus ensuring
|
||||
packets are delivered exactly in the order they are sent.
|
||||
|
||||
For unreliable packets, ENet will simply discard the lower sequence
|
||||
number packet if a packet with a higher sequence number has already
|
||||
been delivered. This allows the packets to be dispatched immediately
|
||||
as they arrive, and reduce latency of unreliable packets to an
|
||||
absolute minimum. For reliable packets, if a higher sequence number
|
||||
packet arrives, but the preceding packets in the sequence have not yet
|
||||
arrived, ENet will stall delivery of the higher sequence number
|
||||
packets until its predecessors have arrived.
|
||||
|
||||
@section Channels Channels
|
||||
|
||||
Since ENet will stall delivery of reliable packets to ensure proper
|
||||
sequencing, and consequently any packets of higher sequence number
|
||||
whether reliable or unreliable, in the event the reliable packet's
|
||||
predecessors have not yet arrived, this can introduce latency into the
|
||||
delivery of other packets which may not need to be as strictly ordered
|
||||
with respect to the packet that stalled their delivery.
|
||||
|
||||
To combat this latency and reduce the ordering restrictions on
|
||||
packets, ENet provides multiple channels of communication over a given
|
||||
connection. Each channel is independently sequenced, and so the
|
||||
delivery status of a packet in one channel will not stall the delivery
|
||||
of other packets in another channel.
|
||||
|
||||
@section Reliability Reliability
|
||||
|
||||
ENet provides optional reliability of packet delivery by ensuring the
|
||||
foreign host acknowledges receipt of all reliable packets. ENet will
|
||||
attempt to resend the packet up to a reasonable amount of times, if no
|
||||
acknowledgement of the packet's receipt happens within a specified
|
||||
timeout. Retry timeouts are progressive and become more lenient with
|
||||
every failed attempt to allow for temporary turbulence in network
|
||||
conditions.
|
||||
|
||||
@section FaR Fragmentation and Reassembly
|
||||
|
||||
ENet will send and deliver packets regardless of size. Large packets
|
||||
are fragmented into many smaller packets of suitable size, and
|
||||
reassembled on the foreign host to recover the original packet for
|
||||
delivery. The process is entirely transparent to the developer.
|
||||
|
||||
@section Aggregation Aggregation
|
||||
|
||||
ENet aggregates all protocol commands, including acknowledgements and
|
||||
packet transfer, into larger protocol packets to ensure the proper
|
||||
utilization of the connection and to limit the opportunities for
|
||||
packet loss that might otherwise result in further delivery latency.
|
||||
|
||||
@section Adaptability Adaptability
|
||||
|
||||
ENet provides an in-flight data window for reliable packets to ensure
|
||||
connections are not overwhelmed by volumes of packets. It also
|
||||
provides a static bandwidth allocation mechanism to ensure the total
|
||||
volume of packets sent and received to a host don't exceed the host's
|
||||
capabilities. Further, ENet also provides a dynamic throttle that
|
||||
responds to deviations from normal network connections to rectify
|
||||
various types of network congestion by further limiting the volume of
|
||||
packets sent.
|
||||
|
||||
@section Portability Portability
|
||||
|
||||
ENet works on Windows and any other Unix or Unix-like platform
|
||||
providing a BSD sockets interface. The library has a small and stable
|
||||
code base that can easily be extended to support other platforms and
|
||||
integrates easily. ENet makes no assumptions about the underlying
|
||||
platform's endianess or word size.
|
||||
|
||||
@section Freedom Freedom
|
||||
|
||||
ENet demands no royalties and doesn't carry a viral license that would
|
||||
restrict you in how you might use it in your programs. ENet is
|
||||
licensed under a short-and-sweet MIT-style license, which gives you
|
||||
the freedom to do anything you want with it (well, almost anything).
|
||||
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
@page Installation Installation
|
||||
|
||||
ENet should be trivially simple to integrate with most applications.
|
||||
First, make sure you download the latest source distribution at @ref Downloads.
|
||||
|
||||
@section Unix Unix-like Operating Systems
|
||||
|
||||
If you are using an ENet release, then you should simply be able to build it
|
||||
by doing the following:
|
||||
|
||||
./configure && make && make install
|
||||
|
||||
If you obtained the package from github, you must have automake and autoconf
|
||||
available to generate the build system first by doing the following command
|
||||
before using the above mentioned build procedure:
|
||||
|
||||
autoreconf -vfi
|
||||
|
||||
|
||||
@subsection SolarisBSD Solaris and BSD
|
||||
|
||||
When building ENet under Solaris, you must specify the -lsocket and
|
||||
-lnsl parameters to your compiler to ensure that the sockets library
|
||||
is linked in.
|
||||
|
||||
@section Windows Microsoft Windows
|
||||
|
||||
You may simply use the included "enet.lib" or "enet64.lib" static libraries.
|
||||
However, if you wish to build the library yourself, then the following
|
||||
instructions apply:
|
||||
|
||||
There is an included MSVC 6 project (enet.dsp) which you may use to
|
||||
build a suitable library file. Alternatively, you may simply drag all
|
||||
the ENet source files into your main project.
|
||||
|
||||
You will have to link to the Winsock2 libraries, so make sure to add
|
||||
ws2_32.lib and winmm.lib to your library list (Project Settings | Link |
|
||||
Object/library modules).
|
||||
|
||||
@subsection enet.dsp Building with the included enet.dsp
|
||||
|
||||
Load the included enet.dsp. MSVC may ask you to convert it if you
|
||||
are on a newer version of MSVC - just allow the conversion and save
|
||||
the resulting project as "enet" or similar. After you build this
|
||||
project, it will output an "enet.lib" file to either the "Debug/"
|
||||
or "Release/" directory, depending on which configuration you have
|
||||
selected to build. By default, it should produce "Debug/enet.lib".
|
||||
|
||||
You may then copy the resulting "enet.lib" file and the header files
|
||||
found in the "include/" directory to your other projects and add it to
|
||||
their library lists. Make sure to also link against "ws2_32.lib" and
|
||||
"winmm.lib" as described above.
|
||||
|
||||
@subsection DLL DLL
|
||||
|
||||
If you wish to build ENet as a DLL you must first define ENET_DLL
|
||||
within the project (Project Settings | C/C++ | Preprocessor |
|
||||
Preprocessor definitions) or, more invasively, simply define ENET_DLL
|
||||
at the top of enet.h.
|
||||
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
@page License License
|
||||
|
||||
Copyright (c) 2002-2024 Lee Salzman
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/** @mainpage ENet
|
||||
|
||||
ENet's purpose is to provide a relatively thin, simple and robust
|
||||
network communication layer on top of UDP (User Datagram Protocol).
|
||||
The primary feature it provides is optional reliable, in-order
|
||||
delivery of packets.
|
||||
|
||||
ENet omits certain higher level networking features such as authentication,
|
||||
lobbying, server discovery, encryption, or other similar tasks that are
|
||||
particularly application specific so that the library remains flexible,
|
||||
portable, and easily embeddable.
|
||||
|
||||
@ref Features
|
||||
|
||||
@ref Downloads
|
||||
|
||||
@ref Installation
|
||||
|
||||
@ref Tutorial
|
||||
|
||||
@ref MailingList
|
||||
|
||||
@ref IRCChannel
|
||||
|
||||
@ref FAQ
|
||||
|
||||
@ref License
|
||||
|
||||
<a class="el" href="usergroup0.html">Documentation</a>
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
@page Downloads Downloads
|
||||
|
||||
You can retrieve the source to ENet by downloading it in either .tar.gz form
|
||||
or accessing the github distribution directly.
|
||||
|
||||
The most recent stable release (1.3.18) can be downloaded <a class="el" href="download/enet-1.3.18.tar.gz">here</a>.
|
||||
The last release that is protocol compatible with the 1.2 series or earlier (1.2.5) can be downloaded <a class="el" href="download/enet-1.2.5.tar.gz">here</a>.
|
||||
|
||||
You can find the most recent ENet source at <a class="el" href="https://github.com/lsalzman/enet">the github repository</a>.
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
@page MailingList Mailing List
|
||||
|
||||
The <a class="el" href="http://lists.cubik.org/mailman/listinfo/enet-discuss">enet-discuss</a> list is for discussion of ENet, including bug reports or feature requests.
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
@page IRCChannel IRC Channel
|
||||
|
||||
Join the \#enet channel on the <a class="el" href="https://libera.chat">Libera Chat IRC network (irc.libera.chat)</a> for real-time discussion about the ENet library.
|
||||
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,366 @@
|
||||
/**
|
||||
@page Tutorial Tutorial
|
||||
|
||||
@ref Initialization
|
||||
|
||||
@ref CreateServer
|
||||
|
||||
@ref CreateClient
|
||||
|
||||
@ref ManageHost
|
||||
|
||||
@ref SendingPacket
|
||||
|
||||
@ref Disconnecting
|
||||
|
||||
@ref Connecting
|
||||
|
||||
@section Initialization Initialization
|
||||
|
||||
You should include the file <enet/enet.h> when using ENet. Do not
|
||||
include <enet.h> without the directory prefix, as this may cause
|
||||
file name conflicts on some systems.
|
||||
|
||||
Before using ENet, you must call enet_initialize() to initialize the
|
||||
library. Upon program exit, you should call enet_deinitialize() so
|
||||
that the library may clean up any used resources.
|
||||
|
||||
@code
|
||||
#include <enet/enet.h>
|
||||
|
||||
int
|
||||
main (int argc, char ** argv)
|
||||
{
|
||||
if (enet_initialize () != 0)
|
||||
{
|
||||
fprintf (stderr, "An error occurred while initializing ENet.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
atexit (enet_deinitialize);
|
||||
...
|
||||
...
|
||||
...
|
||||
}
|
||||
@endcode
|
||||
|
||||
@section CreateServer Creating an ENet server
|
||||
|
||||
Servers in ENet are constructed with enet_host_create(). You must
|
||||
specify an address on which to receive data and new connections, as
|
||||
well as the maximum allowable numbers of connected peers. You may
|
||||
optionally specify the incoming and outgoing bandwidth of the server
|
||||
in bytes per second so that ENet may try to statically manage
|
||||
bandwidth resources among connected peers in addition to its dynamic
|
||||
throttling algorithm; specifying 0 for these two options will cause
|
||||
ENet to rely entirely upon its dynamic throttling algorithm to manage
|
||||
bandwidth.
|
||||
|
||||
When done with a host, the host may be destroyed with
|
||||
enet_host_destroy(). All connected peers to the host will be reset,
|
||||
and the resources used by the host will be freed.
|
||||
|
||||
@code
|
||||
ENetAddress address;
|
||||
ENetHost * server;
|
||||
|
||||
/* Bind the server to the default localhost. */
|
||||
/* A specific host address can be specified by */
|
||||
/* enet_address_set_host (& address, "x.x.x.x"); */
|
||||
|
||||
address.host = ENET_HOST_ANY;
|
||||
/* Bind the server to port 1234. */
|
||||
address.port = 1234;
|
||||
|
||||
server = enet_host_create (& address /* the address to bind the server host to */,
|
||||
32 /* allow up to 32 clients and/or outgoing connections */,
|
||||
2 /* allow up to 2 channels to be used, 0 and 1 */,
|
||||
0 /* assume any amount of incoming bandwidth */,
|
||||
0 /* assume any amount of outgoing bandwidth */);
|
||||
if (server == NULL)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"An error occurred while trying to create an ENet server host.\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
...
|
||||
...
|
||||
...
|
||||
enet_host_destroy(server);
|
||||
@endcode
|
||||
|
||||
@section CreateClient Creating an ENet client
|
||||
|
||||
Clients in ENet are similarly constructed with enet_host_create() when
|
||||
no address is specified to bind the host to. Bandwidth may be
|
||||
specified for the client host as in the above example. The peer count
|
||||
controls the maximum number of connections to other server hosts that
|
||||
may be simultaneously open.
|
||||
|
||||
@code
|
||||
ENetHost * client;
|
||||
|
||||
client = enet_host_create (NULL /* create a client host */,
|
||||
1 /* only allow 1 outgoing connection */,
|
||||
2 /* allow up 2 channels to be used, 0 and 1 */,
|
||||
0 /* assume any amount of incoming bandwidth */,
|
||||
0 /* assume any amount of outgoing bandwidth */);
|
||||
|
||||
if (client == NULL)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"An error occurred while trying to create an ENet client host.\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
...
|
||||
...
|
||||
...
|
||||
enet_host_destroy(client);
|
||||
@endcode
|
||||
|
||||
@section ManageHost Managing an ENet host
|
||||
|
||||
ENet uses a polled event model to notify the programmer of significant
|
||||
events. ENet hosts are polled for events with enet_host_service(),
|
||||
where an optional timeout value in milliseconds may be specified to
|
||||
control how long ENet will poll; if a timeout of 0 is specified,
|
||||
enet_host_service() will return immediately if there are no events to
|
||||
dispatch. enet_host_service() will return 1 if an event was dispatched
|
||||
within the specified timeout.
|
||||
|
||||
Beware that most processing of the network with the ENet stack is done
|
||||
inside enet_host_service(). Both hosts that make up the sides of a connection
|
||||
must regularly call this function to ensure packets are actually sent and
|
||||
received. A common symptom of not actively calling enet_host_service()
|
||||
on both ends is that one side receives events while the other does not.
|
||||
The best way to schedule this activity to ensure adequate service is, for
|
||||
example, to call enet_host_service() with a 0 timeout (meaning non-blocking)
|
||||
at the beginning of every frame in a game loop.
|
||||
|
||||
Currently there are only four types of significant events in ENet:
|
||||
|
||||
An event of type ENET_EVENT_TYPE_NONE is returned if no event occurred
|
||||
within the specified time limit. enet_host_service() will return 0
|
||||
with this event.
|
||||
|
||||
An event of type ENET_EVENT_TYPE_CONNECT is returned when either a new client
|
||||
host has connected to the server host or when an attempt to establish a
|
||||
connection with a foreign host has succeeded. Only the "peer" field of the
|
||||
event structure is valid for this event and contains the newly connected peer.
|
||||
|
||||
An event of type ENET_EVENT_TYPE_RECEIVE is returned when a packet is received
|
||||
from a connected peer. The "peer" field contains the peer the packet was
|
||||
received from, "channelID" is the channel on which the packet was sent, and
|
||||
"packet" is the packet that was sent. The packet contained in the "packet"
|
||||
field must be destroyed with enet_packet_destroy() when you are done
|
||||
inspecting its contents.
|
||||
|
||||
An event of type ENET_EVENT_TYPE_DISCONNECT is returned when a connected peer
|
||||
has either explicitly disconnected or timed out. Only the "peer" field of the
|
||||
event structure is valid for this event and contains the peer that
|
||||
disconnected. Only the "data" field of the peer is still valid on a
|
||||
disconnect event and must be explicitly reset.
|
||||
|
||||
@code
|
||||
ENetEvent event;
|
||||
|
||||
/* Wait up to 1000 milliseconds for an event. */
|
||||
while (enet_host_service (client, & event, 1000) > 0)
|
||||
{
|
||||
switch (event.type)
|
||||
{
|
||||
case ENET_EVENT_TYPE_CONNECT:
|
||||
printf ("A new client connected from %x:%u.\n",
|
||||
event.peer -> address.host,
|
||||
event.peer -> address.port);
|
||||
|
||||
/* Store any relevant client information here. */
|
||||
event.peer -> data = "Client information";
|
||||
|
||||
break;
|
||||
|
||||
case ENET_EVENT_TYPE_RECEIVE:
|
||||
printf ("A packet of length %u containing %s was received from %s on channel %u.\n",
|
||||
event.packet -> dataLength,
|
||||
event.packet -> data,
|
||||
event.peer -> data,
|
||||
event.channelID);
|
||||
|
||||
/* Clean up the packet now that we're done using it. */
|
||||
enet_packet_destroy (event.packet);
|
||||
|
||||
break;
|
||||
|
||||
case ENET_EVENT_TYPE_DISCONNECT:
|
||||
printf ("%s disconnected.\n", event.peer -> data);
|
||||
|
||||
/* Reset the peer's client information. */
|
||||
|
||||
event.peer -> data = NULL;
|
||||
}
|
||||
}
|
||||
...
|
||||
...
|
||||
...
|
||||
@endcode
|
||||
|
||||
@section SendingPacket Sending a packet to an ENet peer
|
||||
|
||||
Packets in ENet are created with enet_packet_create(), where the size
|
||||
of the packet must be specified. Optionally, initial data may be
|
||||
specified to copy into the packet.
|
||||
|
||||
Certain flags may also be supplied to enet_packet_create() to control
|
||||
various packet features:
|
||||
|
||||
ENET_PACKET_FLAG_RELIABLE specifies that the packet must use reliable
|
||||
delivery. A reliable packet is guaranteed to be delivered, and a
|
||||
number of retry attempts will be made until an acknowledgement is
|
||||
received from the foreign host the packet is sent to. If a certain
|
||||
number of retry attempts is reached without any acknowledgement, ENet
|
||||
will assume the peer has disconnected and forcefully reset the
|
||||
connection. If this flag is not specified, the packet is assumed an
|
||||
unreliable packet, and no retry attempts will be made nor
|
||||
acknowledgements generated.
|
||||
|
||||
A packet may be resized (extended or truncated) with
|
||||
enet_packet_resize().
|
||||
|
||||
A packet is sent to a foreign host with
|
||||
enet_peer_send(). enet_peer_send() accepts a channel id over which to
|
||||
send the packet to a given peer. Once the packet is handed over to
|
||||
ENet with enet_peer_send(), ENet will handle its deallocation and
|
||||
enet_packet_destroy() should not be used upon it.
|
||||
|
||||
One may also use enet_host_broadcast() to send a packet to all
|
||||
connected peers on a given host over a specified channel id, as with
|
||||
enet_peer_send().
|
||||
|
||||
Queued packets will be sent on a call to enet_host_service().
|
||||
Alternatively, enet_host_flush() will send out queued packets without
|
||||
dispatching any events.
|
||||
|
||||
@code
|
||||
/* Create a reliable packet of size 7 containing "packet\0" */
|
||||
ENetPacket * packet = enet_packet_create ("packet",
|
||||
strlen ("packet") + 1,
|
||||
ENET_PACKET_FLAG_RELIABLE);
|
||||
|
||||
/* Extend the packet so and append the string "foo", so it now */
|
||||
/* contains "packetfoo\0" */
|
||||
enet_packet_resize (packet, strlen ("packetfoo") + 1);
|
||||
strcpy (& packet -> data [strlen ("packet")], "foo");
|
||||
|
||||
/* Send the packet to the peer over channel id 0. */
|
||||
/* One could also broadcast the packet by */
|
||||
/* enet_host_broadcast (host, 0, packet); */
|
||||
enet_peer_send (peer, 0, packet);
|
||||
...
|
||||
...
|
||||
...
|
||||
/* One could just use enet_host_service() instead. */
|
||||
enet_host_flush (host);
|
||||
@endcode
|
||||
|
||||
@section Disconnecting Disconnecting an ENet peer
|
||||
|
||||
Peers may be gently disconnected with enet_peer_disconnect(). A
|
||||
disconnect request will be sent to the foreign host, and ENet will
|
||||
wait for an acknowledgement from the foreign host before finally
|
||||
disconnecting. An event of type ENET_EVENT_TYPE_DISCONNECT will be
|
||||
generated once the disconnection succeeds. Normally timeouts apply to
|
||||
the disconnect acknowledgement, and so if no acknowledgement is
|
||||
received after a length of time the peer will be forcefully
|
||||
disconnected.
|
||||
|
||||
enet_peer_reset() will forcefully disconnect a peer. The foreign host
|
||||
will get no notification of a disconnect and will time out on the
|
||||
foreign host. No event is generated.
|
||||
|
||||
@code
|
||||
ENetEvent event;
|
||||
|
||||
enet_peer_disconnect (peer, 0);
|
||||
|
||||
/* Allow up to 3 seconds for the disconnect to succeed
|
||||
* and drop any packets received packets.
|
||||
*/
|
||||
while (enet_host_service (client, & event, 3000) > 0)
|
||||
{
|
||||
switch (event.type)
|
||||
{
|
||||
case ENET_EVENT_TYPE_RECEIVE:
|
||||
enet_packet_destroy (event.packet);
|
||||
break;
|
||||
|
||||
case ENET_EVENT_TYPE_DISCONNECT:
|
||||
puts ("Disconnection succeeded.");
|
||||
return;
|
||||
...
|
||||
...
|
||||
...
|
||||
}
|
||||
}
|
||||
|
||||
/* We've arrived here, so the disconnect attempt didn't */
|
||||
/* succeed yet. Force the connection down. */
|
||||
enet_peer_reset (peer);
|
||||
...
|
||||
...
|
||||
...
|
||||
@endcode
|
||||
|
||||
@section Connecting Connecting to an ENet host
|
||||
|
||||
A connection to a foreign host is initiated with enet_host_connect().
|
||||
It accepts the address of a foreign host to connect to, and the number
|
||||
of channels that should be allocated for communication. If N channels
|
||||
are allocated for use, their channel ids will be numbered 0 through
|
||||
N-1. A peer representing the connection attempt is returned, or NULL
|
||||
if there were no available peers over which to initiate the
|
||||
connection. When the connection attempt succeeds, an event of type
|
||||
ENET_EVENT_TYPE_CONNECT will be generated. If the connection attempt
|
||||
times out or otherwise fails, an event of type
|
||||
ENET_EVENT_TYPE_DISCONNECT will be generated.
|
||||
|
||||
@code
|
||||
ENetAddress address;
|
||||
ENetEvent event;
|
||||
ENetPeer *peer;
|
||||
|
||||
/* Connect to some.server.net:1234. */
|
||||
enet_address_set_host (& address, "some.server.net");
|
||||
address.port = 1234;
|
||||
|
||||
/* Initiate the connection, allocating the two channels 0 and 1. */
|
||||
peer = enet_host_connect (client, & address, 2, 0);
|
||||
|
||||
if (peer == NULL)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"No available peers for initiating an ENet connection.\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Wait up to 5 seconds for the connection attempt to succeed. */
|
||||
if (enet_host_service (client, & event, 5000) > 0 &&
|
||||
event.type == ENET_EVENT_TYPE_CONNECT)
|
||||
{
|
||||
puts ("Connection to some.server.net:1234 succeeded.");
|
||||
...
|
||||
...
|
||||
...
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Either the 5 seconds are up or a disconnect event was */
|
||||
/* received. Reset the peer in the event the 5 seconds */
|
||||
/* had run out without any significant event. */
|
||||
enet_peer_reset (peer);
|
||||
|
||||
puts ("Connection to some.server.net:1234 failed.");
|
||||
}
|
||||
...
|
||||
...
|
||||
...
|
||||
@endcode
|
||||
*/
|
||||
@@ -0,0 +1,168 @@
|
||||
# Microsoft Developer Studio Project File - Name="enet" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=enet - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "enet.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "enet.mak" CFG="enet - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "enet - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "enet - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "enet - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
MTL=midl.exe
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /O2 /I "include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FD /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "enet - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Target_Dir ""
|
||||
MTL=midl.exe
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /G6 /MTd /W3 /ZI /Od /I "include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /FD /GZ /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "enet - Win32 Release"
|
||||
# Name "enet - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\host.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\list.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\callbacks.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\compress.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\packet.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\peer.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\protocol.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\unix.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\win32.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\include\enet\enet.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\include\enet\list.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\include\enet\callbacks.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\include\enet\protocol.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\include\enet\time.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\include\enet\types.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\include\enet\unix.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\include\enet\utility.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\include\enet\win32.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<CodeBlocks_project_file>
|
||||
<FileVersion major="1" minor="6" />
|
||||
<Project>
|
||||
<Option title="enet_dll" />
|
||||
<Option pch_mode="2" />
|
||||
<Option compiler="gcc" />
|
||||
<Build>
|
||||
<Target title="Debug">
|
||||
<Option output="bin\Debug\libenet" prefix_auto="1" extension_auto="1" />
|
||||
<Option object_output="obj\Debug\" />
|
||||
<Option type="3" />
|
||||
<Option compiler="gcc" />
|
||||
<Option createDefFile="1" />
|
||||
<Option createStaticLib="1" />
|
||||
<Compiler>
|
||||
<Add option="-g" />
|
||||
</Compiler>
|
||||
</Target>
|
||||
<Target title="Release">
|
||||
<Option output="bin\Release\libenet" prefix_auto="1" extension_auto="1" />
|
||||
<Option object_output="obj\Release\" />
|
||||
<Option type="3" />
|
||||
<Option compiler="gcc" />
|
||||
<Option createDefFile="1" />
|
||||
<Option createStaticLib="1" />
|
||||
<Compiler>
|
||||
<Add option="-O2" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-s" />
|
||||
</Linker>
|
||||
</Target>
|
||||
</Build>
|
||||
<Compiler>
|
||||
<Add option="-Wall" />
|
||||
<Add option="-DENET_DLL" />
|
||||
<Add directory="include" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add library="ws2_32" />
|
||||
<Add library="Winmm" />
|
||||
</Linker>
|
||||
<Unit filename="callbacks.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="compress.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="host.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="include\enet\callbacks.h" />
|
||||
<Unit filename="include\enet\enet.h" />
|
||||
<Unit filename="include\enet\list.h" />
|
||||
<Unit filename="include\enet\protocol.h" />
|
||||
<Unit filename="include\enet\time.h" />
|
||||
<Unit filename="include\enet\types.h" />
|
||||
<Unit filename="include\enet\unix.h" />
|
||||
<Unit filename="include\enet\utility.h" />
|
||||
<Unit filename="include\enet\win32.h" />
|
||||
<Unit filename="list.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="packet.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="peer.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="protocol.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="unix.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="win32.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Extensions>
|
||||
<code_completion />
|
||||
<envvars />
|
||||
<debugger />
|
||||
</Extensions>
|
||||
</Project>
|
||||
</CodeBlocks_project_file>
|
||||
@@ -0,0 +1,503 @@
|
||||
/**
|
||||
@file host.c
|
||||
@brief ENet host management functions
|
||||
*/
|
||||
#define ENET_BUILDING_LIB 1
|
||||
#include <string.h>
|
||||
#include "enet/enet.h"
|
||||
|
||||
/** @defgroup host ENet host functions
|
||||
@{
|
||||
*/
|
||||
|
||||
/** Creates a host for communicating to peers.
|
||||
|
||||
@param address the address at which other peers may connect to this host. If NULL, then no peers may connect to the host.
|
||||
@param peerCount the maximum number of peers that should be allocated for the host.
|
||||
@param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT
|
||||
@param incomingBandwidth downstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth.
|
||||
@param outgoingBandwidth upstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth.
|
||||
|
||||
@returns the host on success and NULL on failure
|
||||
|
||||
@remarks ENet will strategically drop packets on specific sides of a connection between hosts
|
||||
to ensure the host's bandwidth is not overwhelmed. The bandwidth parameters also determine
|
||||
the window size of a connection which limits the amount of reliable packets that may be in transit
|
||||
at any given time.
|
||||
*/
|
||||
ENetHost *
|
||||
enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelLimit, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
|
||||
{
|
||||
ENetHost * host;
|
||||
ENetPeer * currentPeer;
|
||||
|
||||
if (peerCount > ENET_PROTOCOL_MAXIMUM_PEER_ID)
|
||||
return NULL;
|
||||
|
||||
host = (ENetHost *) enet_malloc (sizeof (ENetHost));
|
||||
if (host == NULL)
|
||||
return NULL;
|
||||
memset (host, 0, sizeof (ENetHost));
|
||||
|
||||
host -> peers = (ENetPeer *) enet_malloc (peerCount * sizeof (ENetPeer));
|
||||
if (host -> peers == NULL)
|
||||
{
|
||||
enet_free (host);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
memset (host -> peers, 0, peerCount * sizeof (ENetPeer));
|
||||
|
||||
host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM);
|
||||
if (host -> socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket, address) < 0))
|
||||
{
|
||||
if (host -> socket != ENET_SOCKET_NULL)
|
||||
enet_socket_destroy (host -> socket);
|
||||
|
||||
enet_free (host -> peers);
|
||||
enet_free (host);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
enet_socket_set_option (host -> socket, ENET_SOCKOPT_NONBLOCK, 1);
|
||||
enet_socket_set_option (host -> socket, ENET_SOCKOPT_BROADCAST, 1);
|
||||
enet_socket_set_option (host -> socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE);
|
||||
enet_socket_set_option (host -> socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE);
|
||||
|
||||
if (address != NULL && enet_socket_get_address (host -> socket, & host -> address) < 0)
|
||||
host -> address = * address;
|
||||
|
||||
if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
|
||||
channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
|
||||
else
|
||||
if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
|
||||
channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
|
||||
|
||||
host -> randomSeed = (enet_uint32) (size_t) host;
|
||||
host -> randomSeed += enet_host_random_seed ();
|
||||
host -> randomSeed = (host -> randomSeed << 16) | (host -> randomSeed >> 16);
|
||||
host -> channelLimit = channelLimit;
|
||||
host -> incomingBandwidth = incomingBandwidth;
|
||||
host -> outgoingBandwidth = outgoingBandwidth;
|
||||
host -> bandwidthThrottleEpoch = 0;
|
||||
host -> recalculateBandwidthLimits = 0;
|
||||
host -> mtu = ENET_HOST_DEFAULT_MTU;
|
||||
host -> peerCount = peerCount;
|
||||
host -> commandCount = 0;
|
||||
host -> bufferCount = 0;
|
||||
host -> checksum = NULL;
|
||||
host -> receivedAddress.host = ENET_HOST_ANY;
|
||||
host -> receivedAddress.port = 0;
|
||||
host -> receivedData = NULL;
|
||||
host -> receivedDataLength = 0;
|
||||
|
||||
host -> totalSentData = 0;
|
||||
host -> totalSentPackets = 0;
|
||||
host -> totalReceivedData = 0;
|
||||
host -> totalReceivedPackets = 0;
|
||||
host -> totalQueued = 0;
|
||||
|
||||
host -> connectedPeers = 0;
|
||||
host -> bandwidthLimitedPeers = 0;
|
||||
host -> duplicatePeers = ENET_PROTOCOL_MAXIMUM_PEER_ID;
|
||||
host -> maximumPacketSize = ENET_HOST_DEFAULT_MAXIMUM_PACKET_SIZE;
|
||||
host -> maximumWaitingData = ENET_HOST_DEFAULT_MAXIMUM_WAITING_DATA;
|
||||
|
||||
host -> compressor.context = NULL;
|
||||
host -> compressor.compress = NULL;
|
||||
host -> compressor.decompress = NULL;
|
||||
host -> compressor.destroy = NULL;
|
||||
|
||||
host -> intercept = NULL;
|
||||
|
||||
enet_list_clear (& host -> dispatchQueue);
|
||||
|
||||
for (currentPeer = host -> peers;
|
||||
currentPeer < & host -> peers [host -> peerCount];
|
||||
++ currentPeer)
|
||||
{
|
||||
currentPeer -> host = host;
|
||||
currentPeer -> incomingPeerID = currentPeer - host -> peers;
|
||||
currentPeer -> outgoingSessionID = currentPeer -> incomingSessionID = 0xFF;
|
||||
currentPeer -> data = NULL;
|
||||
|
||||
enet_list_clear (& currentPeer -> acknowledgements);
|
||||
enet_list_clear (& currentPeer -> sentReliableCommands);
|
||||
enet_list_clear (& currentPeer -> outgoingCommands);
|
||||
enet_list_clear (& currentPeer -> outgoingSendReliableCommands);
|
||||
enet_list_clear (& currentPeer -> dispatchedCommands);
|
||||
|
||||
enet_peer_reset (currentPeer);
|
||||
}
|
||||
|
||||
return host;
|
||||
}
|
||||
|
||||
/** Destroys the host and all resources associated with it.
|
||||
@param host pointer to the host to destroy
|
||||
*/
|
||||
void
|
||||
enet_host_destroy (ENetHost * host)
|
||||
{
|
||||
ENetPeer * currentPeer;
|
||||
|
||||
if (host == NULL)
|
||||
return;
|
||||
|
||||
enet_socket_destroy (host -> socket);
|
||||
|
||||
for (currentPeer = host -> peers;
|
||||
currentPeer < & host -> peers [host -> peerCount];
|
||||
++ currentPeer)
|
||||
{
|
||||
enet_peer_reset (currentPeer);
|
||||
}
|
||||
|
||||
if (host -> compressor.context != NULL && host -> compressor.destroy)
|
||||
(* host -> compressor.destroy) (host -> compressor.context);
|
||||
|
||||
enet_free (host -> peers);
|
||||
enet_free (host);
|
||||
}
|
||||
|
||||
enet_uint32
|
||||
enet_host_random (ENetHost * host)
|
||||
{
|
||||
/* Mulberry32 by Tommy Ettinger */
|
||||
enet_uint32 n = (host -> randomSeed += 0x6D2B79F5U);
|
||||
n = (n ^ (n >> 15)) * (n | 1U);
|
||||
n ^= n + (n ^ (n >> 7)) * (n | 61U);
|
||||
return n ^ (n >> 14);
|
||||
}
|
||||
|
||||
/** Initiates a connection to a foreign host.
|
||||
@param host host seeking the connection
|
||||
@param address destination for the connection
|
||||
@param channelCount number of channels to allocate
|
||||
@param data user data supplied to the receiving host
|
||||
@returns a peer representing the foreign host on success, NULL on failure
|
||||
@remarks The peer returned will have not completed the connection until enet_host_service()
|
||||
notifies of an ENET_EVENT_TYPE_CONNECT event for the peer.
|
||||
*/
|
||||
ENetPeer *
|
||||
enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelCount, enet_uint32 data)
|
||||
{
|
||||
ENetPeer * currentPeer;
|
||||
ENetChannel * channel;
|
||||
ENetProtocol command;
|
||||
|
||||
if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
|
||||
channelCount = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
|
||||
else
|
||||
if (channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
|
||||
channelCount = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
|
||||
|
||||
for (currentPeer = host -> peers;
|
||||
currentPeer < & host -> peers [host -> peerCount];
|
||||
++ currentPeer)
|
||||
{
|
||||
if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED)
|
||||
break;
|
||||
}
|
||||
|
||||
if (currentPeer >= & host -> peers [host -> peerCount])
|
||||
return NULL;
|
||||
|
||||
currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel));
|
||||
if (currentPeer -> channels == NULL)
|
||||
return NULL;
|
||||
currentPeer -> channelCount = channelCount;
|
||||
currentPeer -> state = ENET_PEER_STATE_CONNECTING;
|
||||
currentPeer -> address = * address;
|
||||
currentPeer -> connectID = enet_host_random (host);
|
||||
currentPeer -> mtu = host -> mtu;
|
||||
|
||||
if (host -> outgoingBandwidth == 0)
|
||||
currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
|
||||
else
|
||||
currentPeer -> windowSize = (host -> outgoingBandwidth /
|
||||
ENET_PEER_WINDOW_SIZE_SCALE) *
|
||||
ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
|
||||
|
||||
if (currentPeer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
|
||||
currentPeer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
|
||||
else
|
||||
if (currentPeer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
|
||||
currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
|
||||
|
||||
for (channel = currentPeer -> channels;
|
||||
channel < & currentPeer -> channels [channelCount];
|
||||
++ channel)
|
||||
{
|
||||
channel -> outgoingReliableSequenceNumber = 0;
|
||||
channel -> outgoingUnreliableSequenceNumber = 0;
|
||||
channel -> incomingReliableSequenceNumber = 0;
|
||||
channel -> incomingUnreliableSequenceNumber = 0;
|
||||
|
||||
enet_list_clear (& channel -> incomingReliableCommands);
|
||||
enet_list_clear (& channel -> incomingUnreliableCommands);
|
||||
|
||||
channel -> usedReliableWindows = 0;
|
||||
memset (channel -> reliableWindows, 0, sizeof (channel -> reliableWindows));
|
||||
}
|
||||
|
||||
command.header.command = ENET_PROTOCOL_COMMAND_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
|
||||
command.header.channelID = 0xFF;
|
||||
command.connect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID);
|
||||
command.connect.incomingSessionID = currentPeer -> incomingSessionID;
|
||||
command.connect.outgoingSessionID = currentPeer -> outgoingSessionID;
|
||||
command.connect.mtu = ENET_HOST_TO_NET_32 (currentPeer -> mtu);
|
||||
command.connect.windowSize = ENET_HOST_TO_NET_32 (currentPeer -> windowSize);
|
||||
command.connect.channelCount = ENET_HOST_TO_NET_32 (channelCount);
|
||||
command.connect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth);
|
||||
command.connect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
|
||||
command.connect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval);
|
||||
command.connect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration);
|
||||
command.connect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration);
|
||||
command.connect.connectID = currentPeer -> connectID;
|
||||
command.connect.data = ENET_HOST_TO_NET_32 (data);
|
||||
|
||||
enet_peer_queue_outgoing_command (currentPeer, & command, NULL, 0, 0);
|
||||
|
||||
return currentPeer;
|
||||
}
|
||||
|
||||
/** Queues a packet to be sent to all peers associated with the host.
|
||||
@param host host on which to broadcast the packet
|
||||
@param channelID channel on which to broadcast
|
||||
@param packet packet to broadcast
|
||||
*/
|
||||
void
|
||||
enet_host_broadcast (ENetHost * host, enet_uint8 channelID, ENetPacket * packet)
|
||||
{
|
||||
ENetPeer * currentPeer;
|
||||
|
||||
for (currentPeer = host -> peers;
|
||||
currentPeer < & host -> peers [host -> peerCount];
|
||||
++ currentPeer)
|
||||
{
|
||||
if (currentPeer -> state != ENET_PEER_STATE_CONNECTED)
|
||||
continue;
|
||||
|
||||
enet_peer_send (currentPeer, channelID, packet);
|
||||
}
|
||||
|
||||
if (packet -> referenceCount == 0)
|
||||
enet_packet_destroy (packet);
|
||||
}
|
||||
|
||||
/** Sets the packet compressor the host should use to compress and decompress packets.
|
||||
@param host host to enable or disable compression for
|
||||
@param compressor callbacks for for the packet compressor; if NULL, then compression is disabled
|
||||
*/
|
||||
void
|
||||
enet_host_compress (ENetHost * host, const ENetCompressor * compressor)
|
||||
{
|
||||
if (host -> compressor.context != NULL && host -> compressor.destroy)
|
||||
(* host -> compressor.destroy) (host -> compressor.context);
|
||||
|
||||
if (compressor)
|
||||
host -> compressor = * compressor;
|
||||
else
|
||||
host -> compressor.context = NULL;
|
||||
}
|
||||
|
||||
/** Limits the maximum allowed channels of future incoming connections.
|
||||
@param host host to limit
|
||||
@param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT
|
||||
*/
|
||||
void
|
||||
enet_host_channel_limit (ENetHost * host, size_t channelLimit)
|
||||
{
|
||||
if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
|
||||
channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
|
||||
else
|
||||
if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
|
||||
channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
|
||||
|
||||
host -> channelLimit = channelLimit;
|
||||
}
|
||||
|
||||
|
||||
/** Adjusts the bandwidth limits of a host.
|
||||
@param host host to adjust
|
||||
@param incomingBandwidth new incoming bandwidth
|
||||
@param outgoingBandwidth new outgoing bandwidth
|
||||
@remarks the incoming and outgoing bandwidth parameters are identical in function to those
|
||||
specified in enet_host_create().
|
||||
*/
|
||||
void
|
||||
enet_host_bandwidth_limit (ENetHost * host, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
|
||||
{
|
||||
host -> incomingBandwidth = incomingBandwidth;
|
||||
host -> outgoingBandwidth = outgoingBandwidth;
|
||||
host -> recalculateBandwidthLimits = 1;
|
||||
}
|
||||
|
||||
void
|
||||
enet_host_bandwidth_throttle (ENetHost * host)
|
||||
{
|
||||
enet_uint32 timeCurrent = enet_time_get (),
|
||||
elapsedTime = timeCurrent - host -> bandwidthThrottleEpoch,
|
||||
peersRemaining = (enet_uint32) host -> connectedPeers,
|
||||
dataTotal = ~0,
|
||||
bandwidth = ~0,
|
||||
throttle = 0,
|
||||
bandwidthLimit = 0;
|
||||
int needsAdjustment = host -> bandwidthLimitedPeers > 0 ? 1 : 0;
|
||||
ENetPeer * peer;
|
||||
ENetProtocol command;
|
||||
|
||||
if (elapsedTime < ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL)
|
||||
return;
|
||||
|
||||
host -> bandwidthThrottleEpoch = timeCurrent;
|
||||
|
||||
if (peersRemaining == 0)
|
||||
return;
|
||||
|
||||
if (host -> outgoingBandwidth != 0)
|
||||
{
|
||||
dataTotal = 0;
|
||||
bandwidth = (host -> outgoingBandwidth * elapsedTime) / 1000;
|
||||
|
||||
for (peer = host -> peers;
|
||||
peer < & host -> peers [host -> peerCount];
|
||||
++ peer)
|
||||
{
|
||||
if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
|
||||
continue;
|
||||
|
||||
dataTotal += peer -> outgoingDataTotal;
|
||||
}
|
||||
}
|
||||
|
||||
while (peersRemaining > 0 && needsAdjustment != 0)
|
||||
{
|
||||
needsAdjustment = 0;
|
||||
|
||||
if (dataTotal <= bandwidth)
|
||||
throttle = ENET_PEER_PACKET_THROTTLE_SCALE;
|
||||
else
|
||||
throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal;
|
||||
|
||||
for (peer = host -> peers;
|
||||
peer < & host -> peers [host -> peerCount];
|
||||
++ peer)
|
||||
{
|
||||
enet_uint32 peerBandwidth;
|
||||
|
||||
if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
|
||||
peer -> incomingBandwidth == 0 ||
|
||||
peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
|
||||
continue;
|
||||
|
||||
peerBandwidth = (peer -> incomingBandwidth * elapsedTime) / 1000;
|
||||
if ((throttle * peer -> outgoingDataTotal) / ENET_PEER_PACKET_THROTTLE_SCALE <= peerBandwidth)
|
||||
continue;
|
||||
|
||||
peer -> packetThrottleLimit = (peerBandwidth *
|
||||
ENET_PEER_PACKET_THROTTLE_SCALE) / peer -> outgoingDataTotal;
|
||||
|
||||
if (peer -> packetThrottleLimit == 0)
|
||||
peer -> packetThrottleLimit = 1;
|
||||
|
||||
if (peer -> packetThrottle > peer -> packetThrottleLimit)
|
||||
peer -> packetThrottle = peer -> packetThrottleLimit;
|
||||
|
||||
peer -> outgoingBandwidthThrottleEpoch = timeCurrent;
|
||||
|
||||
peer -> incomingDataTotal = 0;
|
||||
peer -> outgoingDataTotal = 0;
|
||||
|
||||
needsAdjustment = 1;
|
||||
-- peersRemaining;
|
||||
bandwidth -= peerBandwidth;
|
||||
dataTotal -= peerBandwidth;
|
||||
}
|
||||
}
|
||||
|
||||
if (peersRemaining > 0)
|
||||
{
|
||||
if (dataTotal <= bandwidth)
|
||||
throttle = ENET_PEER_PACKET_THROTTLE_SCALE;
|
||||
else
|
||||
throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal;
|
||||
|
||||
for (peer = host -> peers;
|
||||
peer < & host -> peers [host -> peerCount];
|
||||
++ peer)
|
||||
{
|
||||
if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
|
||||
peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
|
||||
continue;
|
||||
|
||||
peer -> packetThrottleLimit = throttle;
|
||||
|
||||
if (peer -> packetThrottle > peer -> packetThrottleLimit)
|
||||
peer -> packetThrottle = peer -> packetThrottleLimit;
|
||||
|
||||
peer -> incomingDataTotal = 0;
|
||||
peer -> outgoingDataTotal = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (host -> recalculateBandwidthLimits)
|
||||
{
|
||||
host -> recalculateBandwidthLimits = 0;
|
||||
|
||||
peersRemaining = (enet_uint32) host -> connectedPeers;
|
||||
bandwidth = host -> incomingBandwidth;
|
||||
needsAdjustment = 1;
|
||||
|
||||
if (bandwidth == 0)
|
||||
bandwidthLimit = 0;
|
||||
else
|
||||
while (peersRemaining > 0 && needsAdjustment != 0)
|
||||
{
|
||||
needsAdjustment = 0;
|
||||
bandwidthLimit = bandwidth / peersRemaining;
|
||||
|
||||
for (peer = host -> peers;
|
||||
peer < & host -> peers [host -> peerCount];
|
||||
++ peer)
|
||||
{
|
||||
if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
|
||||
peer -> incomingBandwidthThrottleEpoch == timeCurrent)
|
||||
continue;
|
||||
|
||||
if (peer -> outgoingBandwidth > 0 &&
|
||||
peer -> outgoingBandwidth >= bandwidthLimit)
|
||||
continue;
|
||||
|
||||
peer -> incomingBandwidthThrottleEpoch = timeCurrent;
|
||||
|
||||
needsAdjustment = 1;
|
||||
-- peersRemaining;
|
||||
bandwidth -= peer -> outgoingBandwidth;
|
||||
}
|
||||
}
|
||||
|
||||
for (peer = host -> peers;
|
||||
peer < & host -> peers [host -> peerCount];
|
||||
++ peer)
|
||||
{
|
||||
if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
|
||||
continue;
|
||||
|
||||
command.header.command = ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
|
||||
command.header.channelID = 0xFF;
|
||||
command.bandwidthLimit.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
|
||||
|
||||
if (peer -> incomingBandwidthThrottleEpoch == timeCurrent)
|
||||
command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (peer -> outgoingBandwidth);
|
||||
else
|
||||
command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (bandwidthLimit);
|
||||
|
||||
enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
@file callbacks.h
|
||||
@brief ENet callbacks
|
||||
*/
|
||||
#ifndef __ENET_CALLBACKS_H__
|
||||
#define __ENET_CALLBACKS_H__
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct _ENetCallbacks
|
||||
{
|
||||
void * (ENET_CALLBACK * malloc) (size_t size);
|
||||
void (ENET_CALLBACK * free) (void * memory);
|
||||
void (ENET_CALLBACK * no_memory) (void);
|
||||
} ENetCallbacks;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/** @defgroup callbacks ENet internal callbacks
|
||||
@{
|
||||
@ingroup private
|
||||
*/
|
||||
|
||||
extern void * enet_malloc (size_t);
|
||||
extern void enet_free (void *);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ENET_CALLBACKS_H__ */
|
||||
|
||||
@@ -0,0 +1,615 @@
|
||||
/**
|
||||
@file enet.h
|
||||
@brief ENet public header file
|
||||
*/
|
||||
#ifndef __ENET_ENET_H__
|
||||
#define __ENET_ENET_H__
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "enet/win32.h"
|
||||
#else
|
||||
#include "enet/unix.h"
|
||||
#endif
|
||||
|
||||
#include "enet/types.h"
|
||||
#include "enet/protocol.h"
|
||||
#include "enet/list.h"
|
||||
#include "enet/callbacks.h"
|
||||
|
||||
#define ENET_VERSION_MAJOR 1
|
||||
#define ENET_VERSION_MINOR 3
|
||||
#define ENET_VERSION_PATCH 18
|
||||
#define ENET_VERSION_CREATE(major, minor, patch) (((major)<<16) | ((minor)<<8) | (patch))
|
||||
#define ENET_VERSION_GET_MAJOR(version) (((version)>>16)&0xFF)
|
||||
#define ENET_VERSION_GET_MINOR(version) (((version)>>8)&0xFF)
|
||||
#define ENET_VERSION_GET_PATCH(version) ((version)&0xFF)
|
||||
#define ENET_VERSION ENET_VERSION_CREATE(ENET_VERSION_MAJOR, ENET_VERSION_MINOR, ENET_VERSION_PATCH)
|
||||
|
||||
typedef enet_uint32 ENetVersion;
|
||||
|
||||
struct _ENetHost;
|
||||
struct _ENetEvent;
|
||||
struct _ENetPacket;
|
||||
|
||||
typedef enum _ENetSocketType
|
||||
{
|
||||
ENET_SOCKET_TYPE_STREAM = 1,
|
||||
ENET_SOCKET_TYPE_DATAGRAM = 2
|
||||
} ENetSocketType;
|
||||
|
||||
typedef enum _ENetSocketWait
|
||||
{
|
||||
ENET_SOCKET_WAIT_NONE = 0,
|
||||
ENET_SOCKET_WAIT_SEND = (1 << 0),
|
||||
ENET_SOCKET_WAIT_RECEIVE = (1 << 1),
|
||||
ENET_SOCKET_WAIT_INTERRUPT = (1 << 2)
|
||||
} ENetSocketWait;
|
||||
|
||||
typedef enum _ENetSocketOption
|
||||
{
|
||||
ENET_SOCKOPT_NONBLOCK = 1,
|
||||
ENET_SOCKOPT_BROADCAST = 2,
|
||||
ENET_SOCKOPT_RCVBUF = 3,
|
||||
ENET_SOCKOPT_SNDBUF = 4,
|
||||
ENET_SOCKOPT_REUSEADDR = 5,
|
||||
ENET_SOCKOPT_RCVTIMEO = 6,
|
||||
ENET_SOCKOPT_SNDTIMEO = 7,
|
||||
ENET_SOCKOPT_ERROR = 8,
|
||||
ENET_SOCKOPT_NODELAY = 9,
|
||||
ENET_SOCKOPT_TTL = 10
|
||||
} ENetSocketOption;
|
||||
|
||||
typedef enum _ENetSocketShutdown
|
||||
{
|
||||
ENET_SOCKET_SHUTDOWN_READ = 0,
|
||||
ENET_SOCKET_SHUTDOWN_WRITE = 1,
|
||||
ENET_SOCKET_SHUTDOWN_READ_WRITE = 2
|
||||
} ENetSocketShutdown;
|
||||
|
||||
#define ENET_HOST_ANY 0
|
||||
#define ENET_HOST_BROADCAST 0xFFFFFFFFU
|
||||
#define ENET_PORT_ANY 0
|
||||
|
||||
/**
|
||||
* Portable internet address structure.
|
||||
*
|
||||
* The host must be specified in network byte-order, and the port must be in host
|
||||
* byte-order. The constant ENET_HOST_ANY may be used to specify the default
|
||||
* server host. The constant ENET_HOST_BROADCAST may be used to specify the
|
||||
* broadcast address (255.255.255.255). This makes sense for enet_host_connect,
|
||||
* but not for enet_host_create. Once a server responds to a broadcast, the
|
||||
* address is updated from ENET_HOST_BROADCAST to the server's actual IP address.
|
||||
*/
|
||||
typedef struct _ENetAddress
|
||||
{
|
||||
enet_uint32 host;
|
||||
enet_uint16 port;
|
||||
} ENetAddress;
|
||||
|
||||
/**
|
||||
* Packet flag bit constants.
|
||||
*
|
||||
* The host must be specified in network byte-order, and the port must be in
|
||||
* host byte-order. The constant ENET_HOST_ANY may be used to specify the
|
||||
* default server host.
|
||||
|
||||
@sa ENetPacket
|
||||
*/
|
||||
typedef enum _ENetPacketFlag
|
||||
{
|
||||
/** packet must be received by the target peer and resend attempts should be
|
||||
* made until the packet is delivered */
|
||||
ENET_PACKET_FLAG_RELIABLE = (1 << 0),
|
||||
/** packet will not be sequenced with other packets
|
||||
*/
|
||||
ENET_PACKET_FLAG_UNSEQUENCED = (1 << 1),
|
||||
/** packet will not allocate data, and user must supply it instead */
|
||||
ENET_PACKET_FLAG_NO_ALLOCATE = (1 << 2),
|
||||
/** packet will be fragmented using unreliable (instead of reliable) sends
|
||||
* if it exceeds the MTU */
|
||||
ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT = (1 << 3),
|
||||
|
||||
/** whether the packet has been sent from all queues it has been entered into */
|
||||
ENET_PACKET_FLAG_SENT = (1<<8)
|
||||
} ENetPacketFlag;
|
||||
|
||||
typedef void (ENET_CALLBACK * ENetPacketFreeCallback) (struct _ENetPacket *);
|
||||
|
||||
/**
|
||||
* ENet packet structure.
|
||||
*
|
||||
* An ENet data packet that may be sent to or received from a peer. The shown
|
||||
* fields should only be read and never modified. The data field contains the
|
||||
* allocated data for the packet. The dataLength fields specifies the length
|
||||
* of the allocated data. The flags field is either 0 (specifying no flags),
|
||||
* or a bitwise-or of any combination of the following flags:
|
||||
*
|
||||
* ENET_PACKET_FLAG_RELIABLE - packet must be received by the target peer
|
||||
* and resend attempts should be made until the packet is delivered
|
||||
*
|
||||
* ENET_PACKET_FLAG_UNSEQUENCED - packet will not be sequenced with other packets
|
||||
* (not supported for reliable packets)
|
||||
*
|
||||
* ENET_PACKET_FLAG_NO_ALLOCATE - packet will not allocate data, and user must supply it instead
|
||||
*
|
||||
* ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT - packet will be fragmented using unreliable
|
||||
* (instead of reliable) sends if it exceeds the MTU
|
||||
*
|
||||
* ENET_PACKET_FLAG_SENT - whether the packet has been sent from all queues it has been entered into
|
||||
@sa ENetPacketFlag
|
||||
*/
|
||||
typedef struct _ENetPacket
|
||||
{
|
||||
size_t referenceCount; /**< internal use only */
|
||||
enet_uint32 flags; /**< bitwise-or of ENetPacketFlag constants */
|
||||
enet_uint8 * data; /**< allocated data for packet */
|
||||
size_t dataLength; /**< length of data */
|
||||
ENetPacketFreeCallback freeCallback; /**< function to be called when the packet is no longer in use */
|
||||
void * userData; /**< application private data, may be freely modified */
|
||||
} ENetPacket;
|
||||
|
||||
typedef struct _ENetAcknowledgement
|
||||
{
|
||||
ENetListNode acknowledgementList;
|
||||
enet_uint32 sentTime;
|
||||
ENetProtocol command;
|
||||
} ENetAcknowledgement;
|
||||
|
||||
typedef struct _ENetOutgoingCommand
|
||||
{
|
||||
ENetListNode outgoingCommandList;
|
||||
enet_uint16 reliableSequenceNumber;
|
||||
enet_uint16 unreliableSequenceNumber;
|
||||
enet_uint32 sentTime;
|
||||
enet_uint32 roundTripTimeout;
|
||||
enet_uint32 queueTime;
|
||||
enet_uint32 fragmentOffset;
|
||||
enet_uint16 fragmentLength;
|
||||
enet_uint16 sendAttempts;
|
||||
ENetProtocol command;
|
||||
ENetPacket * packet;
|
||||
} ENetOutgoingCommand;
|
||||
|
||||
typedef struct _ENetIncomingCommand
|
||||
{
|
||||
ENetListNode incomingCommandList;
|
||||
enet_uint16 reliableSequenceNumber;
|
||||
enet_uint16 unreliableSequenceNumber;
|
||||
ENetProtocol command;
|
||||
enet_uint32 fragmentCount;
|
||||
enet_uint32 fragmentsRemaining;
|
||||
enet_uint32 * fragments;
|
||||
ENetPacket * packet;
|
||||
} ENetIncomingCommand;
|
||||
|
||||
typedef enum _ENetPeerState
|
||||
{
|
||||
ENET_PEER_STATE_DISCONNECTED = 0,
|
||||
ENET_PEER_STATE_CONNECTING = 1,
|
||||
ENET_PEER_STATE_ACKNOWLEDGING_CONNECT = 2,
|
||||
ENET_PEER_STATE_CONNECTION_PENDING = 3,
|
||||
ENET_PEER_STATE_CONNECTION_SUCCEEDED = 4,
|
||||
ENET_PEER_STATE_CONNECTED = 5,
|
||||
ENET_PEER_STATE_DISCONNECT_LATER = 6,
|
||||
ENET_PEER_STATE_DISCONNECTING = 7,
|
||||
ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT = 8,
|
||||
ENET_PEER_STATE_ZOMBIE = 9
|
||||
} ENetPeerState;
|
||||
|
||||
#ifndef ENET_BUFFER_MAXIMUM
|
||||
#define ENET_BUFFER_MAXIMUM (1 + 2 * ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS)
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
ENET_HOST_RECEIVE_BUFFER_SIZE = 256 * 1024,
|
||||
ENET_HOST_SEND_BUFFER_SIZE = 256 * 1024,
|
||||
ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL = 1000,
|
||||
ENET_HOST_DEFAULT_MTU = 1392,
|
||||
ENET_HOST_DEFAULT_MAXIMUM_PACKET_SIZE = 32 * 1024 * 1024,
|
||||
ENET_HOST_DEFAULT_MAXIMUM_WAITING_DATA = 32 * 1024 * 1024,
|
||||
|
||||
ENET_PEER_DEFAULT_ROUND_TRIP_TIME = 500,
|
||||
ENET_PEER_DEFAULT_PACKET_THROTTLE = 32,
|
||||
ENET_PEER_PACKET_THROTTLE_SCALE = 32,
|
||||
ENET_PEER_PACKET_THROTTLE_COUNTER = 7,
|
||||
ENET_PEER_PACKET_THROTTLE_ACCELERATION = 2,
|
||||
ENET_PEER_PACKET_THROTTLE_DECELERATION = 2,
|
||||
ENET_PEER_PACKET_THROTTLE_INTERVAL = 5000,
|
||||
ENET_PEER_PACKET_LOSS_SCALE = (1 << 16),
|
||||
ENET_PEER_PACKET_LOSS_INTERVAL = 10000,
|
||||
ENET_PEER_WINDOW_SIZE_SCALE = 64 * 1024,
|
||||
ENET_PEER_TIMEOUT_LIMIT = 32,
|
||||
ENET_PEER_TIMEOUT_MINIMUM = 5000,
|
||||
ENET_PEER_TIMEOUT_MAXIMUM = 30000,
|
||||
ENET_PEER_PING_INTERVAL = 500,
|
||||
ENET_PEER_UNSEQUENCED_WINDOWS = 64,
|
||||
ENET_PEER_UNSEQUENCED_WINDOW_SIZE = 1024,
|
||||
ENET_PEER_FREE_UNSEQUENCED_WINDOWS = 32,
|
||||
ENET_PEER_RELIABLE_WINDOWS = 16,
|
||||
ENET_PEER_RELIABLE_WINDOW_SIZE = 0x1000,
|
||||
ENET_PEER_FREE_RELIABLE_WINDOWS = 8
|
||||
};
|
||||
|
||||
typedef struct _ENetChannel
|
||||
{
|
||||
enet_uint16 outgoingReliableSequenceNumber;
|
||||
enet_uint16 outgoingUnreliableSequenceNumber;
|
||||
enet_uint16 usedReliableWindows;
|
||||
enet_uint16 reliableWindows [ENET_PEER_RELIABLE_WINDOWS];
|
||||
enet_uint16 incomingReliableSequenceNumber;
|
||||
enet_uint16 incomingUnreliableSequenceNumber;
|
||||
ENetList incomingReliableCommands;
|
||||
ENetList incomingUnreliableCommands;
|
||||
} ENetChannel;
|
||||
|
||||
typedef enum _ENetPeerFlag
|
||||
{
|
||||
ENET_PEER_FLAG_NEEDS_DISPATCH = (1 << 0),
|
||||
ENET_PEER_FLAG_CONTINUE_SENDING = (1 << 1)
|
||||
} ENetPeerFlag;
|
||||
|
||||
/**
|
||||
* An ENet peer which data packets may be sent or received from.
|
||||
*
|
||||
* No fields should be modified unless otherwise specified.
|
||||
*/
|
||||
typedef struct _ENetPeer
|
||||
{
|
||||
ENetListNode dispatchList;
|
||||
struct _ENetHost * host;
|
||||
enet_uint16 outgoingPeerID;
|
||||
enet_uint16 incomingPeerID;
|
||||
enet_uint32 connectID;
|
||||
enet_uint8 outgoingSessionID;
|
||||
enet_uint8 incomingSessionID;
|
||||
ENetAddress address; /**< Internet address of the peer */
|
||||
void * data; /**< Application private data, may be freely modified */
|
||||
ENetPeerState state;
|
||||
ENetChannel * channels;
|
||||
size_t channelCount; /**< Number of channels allocated for communication with peer */
|
||||
enet_uint32 incomingBandwidth; /**< Downstream bandwidth of the client in bytes/second */
|
||||
enet_uint32 outgoingBandwidth; /**< Upstream bandwidth of the client in bytes/second */
|
||||
enet_uint32 incomingBandwidthThrottleEpoch;
|
||||
enet_uint32 outgoingBandwidthThrottleEpoch;
|
||||
enet_uint32 incomingDataTotal;
|
||||
enet_uint32 outgoingDataTotal;
|
||||
enet_uint32 lastSendTime;
|
||||
enet_uint32 lastReceiveTime;
|
||||
enet_uint32 nextTimeout;
|
||||
enet_uint32 earliestTimeout;
|
||||
enet_uint32 packetLossEpoch;
|
||||
enet_uint32 packetsSent;
|
||||
enet_uint32 packetsLost;
|
||||
enet_uint32 packetLoss; /**< mean packet loss of reliable packets as a ratio with respect to the constant ENET_PEER_PACKET_LOSS_SCALE */
|
||||
enet_uint32 packetLossVariance;
|
||||
enet_uint32 packetThrottle;
|
||||
enet_uint32 packetThrottleLimit;
|
||||
enet_uint32 packetThrottleCounter;
|
||||
enet_uint32 packetThrottleEpoch;
|
||||
enet_uint32 packetThrottleAcceleration;
|
||||
enet_uint32 packetThrottleDeceleration;
|
||||
enet_uint32 packetThrottleInterval;
|
||||
enet_uint32 pingInterval;
|
||||
enet_uint32 timeoutLimit;
|
||||
enet_uint32 timeoutMinimum;
|
||||
enet_uint32 timeoutMaximum;
|
||||
enet_uint32 lastRoundTripTime;
|
||||
enet_uint32 lowestRoundTripTime;
|
||||
enet_uint32 lastRoundTripTimeVariance;
|
||||
enet_uint32 highestRoundTripTimeVariance;
|
||||
enet_uint32 roundTripTime; /**< mean round trip time (RTT), in milliseconds, between sending a reliable packet and receiving its acknowledgement */
|
||||
enet_uint32 roundTripTimeVariance;
|
||||
enet_uint32 mtu;
|
||||
enet_uint32 windowSize;
|
||||
enet_uint32 reliableDataInTransit;
|
||||
enet_uint16 outgoingReliableSequenceNumber;
|
||||
ENetList acknowledgements;
|
||||
ENetList sentReliableCommands;
|
||||
ENetList outgoingSendReliableCommands;
|
||||
ENetList outgoingCommands;
|
||||
ENetList dispatchedCommands;
|
||||
enet_uint16 flags;
|
||||
enet_uint16 reserved;
|
||||
enet_uint16 incomingUnsequencedGroup;
|
||||
enet_uint16 outgoingUnsequencedGroup;
|
||||
enet_uint32 unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32];
|
||||
enet_uint32 eventData;
|
||||
size_t totalWaitingData;
|
||||
} ENetPeer;
|
||||
|
||||
/** An ENet packet compressor for compressing UDP packets before socket sends or receives.
|
||||
*/
|
||||
typedef struct _ENetCompressor
|
||||
{
|
||||
/** Context data for the compressor. Must be non-NULL. */
|
||||
void * context;
|
||||
/** Compresses from inBuffers[0:inBufferCount-1], containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */
|
||||
size_t (ENET_CALLBACK * compress) (void * context, const ENetBuffer * inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 * outData, size_t outLimit);
|
||||
/** Decompresses from inData, containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */
|
||||
size_t (ENET_CALLBACK * decompress) (void * context, const enet_uint8 * inData, size_t inLimit, enet_uint8 * outData, size_t outLimit);
|
||||
/** Destroys the context when compression is disabled or the host is destroyed. May be NULL. */
|
||||
void (ENET_CALLBACK * destroy) (void * context);
|
||||
} ENetCompressor;
|
||||
|
||||
/** Callback that computes the checksum of the data held in buffers[0:bufferCount-1] */
|
||||
typedef enet_uint32 (ENET_CALLBACK * ENetChecksumCallback) (const ENetBuffer * buffers, size_t bufferCount);
|
||||
|
||||
/** Callback for intercepting received raw UDP packets. Should return 1 to intercept, 0 to ignore, or -1 to propagate an error. */
|
||||
typedef int (ENET_CALLBACK * ENetInterceptCallback) (struct _ENetHost * host, struct _ENetEvent * event);
|
||||
|
||||
/** An ENet host for communicating with peers.
|
||||
*
|
||||
* No fields should be modified unless otherwise stated.
|
||||
|
||||
@sa enet_host_create()
|
||||
@sa enet_host_destroy()
|
||||
@sa enet_host_connect()
|
||||
@sa enet_host_service()
|
||||
@sa enet_host_flush()
|
||||
@sa enet_host_broadcast()
|
||||
@sa enet_host_compress()
|
||||
@sa enet_host_compress_with_range_coder()
|
||||
@sa enet_host_channel_limit()
|
||||
@sa enet_host_bandwidth_limit()
|
||||
@sa enet_host_bandwidth_throttle()
|
||||
*/
|
||||
typedef struct _ENetHost
|
||||
{
|
||||
ENetSocket socket;
|
||||
ENetAddress address; /**< Internet address of the host */
|
||||
enet_uint32 incomingBandwidth; /**< downstream bandwidth of the host */
|
||||
enet_uint32 outgoingBandwidth; /**< upstream bandwidth of the host */
|
||||
enet_uint32 bandwidthThrottleEpoch;
|
||||
enet_uint32 mtu;
|
||||
enet_uint32 randomSeed;
|
||||
int recalculateBandwidthLimits;
|
||||
ENetPeer * peers; /**< array of peers allocated for this host */
|
||||
size_t peerCount; /**< number of peers allocated for this host */
|
||||
size_t channelLimit; /**< maximum number of channels allowed for connected peers */
|
||||
enet_uint32 serviceTime;
|
||||
ENetList dispatchQueue;
|
||||
enet_uint32 totalQueued;
|
||||
size_t packetSize;
|
||||
enet_uint16 headerFlags;
|
||||
ENetProtocol commands [ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS];
|
||||
size_t commandCount;
|
||||
ENetBuffer buffers [ENET_BUFFER_MAXIMUM];
|
||||
size_t bufferCount;
|
||||
ENetChecksumCallback checksum; /**< callback the user can set to enable packet checksums for this host */
|
||||
ENetCompressor compressor;
|
||||
enet_uint8 packetData [2][ENET_PROTOCOL_MAXIMUM_MTU];
|
||||
ENetAddress receivedAddress;
|
||||
enet_uint8 * receivedData;
|
||||
size_t receivedDataLength;
|
||||
enet_uint32 totalSentData; /**< total data sent, user should reset to 0 as needed to prevent overflow */
|
||||
enet_uint32 totalSentPackets; /**< total UDP packets sent, user should reset to 0 as needed to prevent overflow */
|
||||
enet_uint32 totalReceivedData; /**< total data received, user should reset to 0 as needed to prevent overflow */
|
||||
enet_uint32 totalReceivedPackets; /**< total UDP packets received, user should reset to 0 as needed to prevent overflow */
|
||||
ENetInterceptCallback intercept; /**< callback the user can set to intercept received raw UDP packets */
|
||||
size_t connectedPeers;
|
||||
size_t bandwidthLimitedPeers;
|
||||
size_t duplicatePeers; /**< optional number of allowed peers from duplicate IPs, defaults to ENET_PROTOCOL_MAXIMUM_PEER_ID */
|
||||
size_t maximumPacketSize; /**< the maximum allowable packet size that may be sent or received on a peer */
|
||||
size_t maximumWaitingData; /**< the maximum aggregate amount of buffer space a peer may use waiting for packets to be delivered */
|
||||
} ENetHost;
|
||||
|
||||
/**
|
||||
* An ENet event type, as specified in @ref ENetEvent.
|
||||
*/
|
||||
typedef enum _ENetEventType
|
||||
{
|
||||
/** no event occurred within the specified time limit */
|
||||
ENET_EVENT_TYPE_NONE = 0,
|
||||
|
||||
/** a connection request initiated by enet_host_connect has completed.
|
||||
* The peer field contains the peer which successfully connected.
|
||||
*/
|
||||
ENET_EVENT_TYPE_CONNECT = 1,
|
||||
|
||||
/** a peer has disconnected. This event is generated on a successful
|
||||
* completion of a disconnect initiated by enet_peer_disconnect, if
|
||||
* a peer has timed out, or if a connection request intialized by
|
||||
* enet_host_connect has timed out. The peer field contains the peer
|
||||
* which disconnected. The data field contains user supplied data
|
||||
* describing the disconnection, or 0, if none is available.
|
||||
*/
|
||||
ENET_EVENT_TYPE_DISCONNECT = 2,
|
||||
|
||||
/** a packet has been received from a peer. The peer field specifies the
|
||||
* peer which sent the packet. The channelID field specifies the channel
|
||||
* number upon which the packet was received. The packet field contains
|
||||
* the packet that was received; this packet must be destroyed with
|
||||
* enet_packet_destroy after use.
|
||||
*/
|
||||
ENET_EVENT_TYPE_RECEIVE = 3
|
||||
} ENetEventType;
|
||||
|
||||
/**
|
||||
* An ENet event as returned by enet_host_service().
|
||||
|
||||
@sa enet_host_service
|
||||
*/
|
||||
typedef struct _ENetEvent
|
||||
{
|
||||
ENetEventType type; /**< type of the event */
|
||||
ENetPeer * peer; /**< peer that generated a connect, disconnect or receive event */
|
||||
enet_uint8 channelID; /**< channel on the peer that generated the event, if appropriate */
|
||||
enet_uint32 data; /**< data associated with the event, if appropriate */
|
||||
ENetPacket * packet; /**< packet associated with the event, if appropriate */
|
||||
} ENetEvent;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/** @defgroup global ENet global functions
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
Initializes ENet globally. Must be called prior to using any functions in
|
||||
ENet.
|
||||
@returns 0 on success, < 0 on failure
|
||||
*/
|
||||
ENET_API int enet_initialize (void);
|
||||
|
||||
/**
|
||||
Initializes ENet globally and supplies user-overridden callbacks. Must be called prior to using any functions in ENet. Do not use enet_initialize() if you use this variant. Make sure the ENetCallbacks structure is zeroed out so that any additional callbacks added in future versions will be properly ignored.
|
||||
|
||||
@param version the constant ENET_VERSION should be supplied so ENet knows which version of ENetCallbacks struct to use
|
||||
@param inits user-overridden callbacks where any NULL callbacks will use ENet's defaults
|
||||
@returns 0 on success, < 0 on failure
|
||||
*/
|
||||
ENET_API int enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits);
|
||||
|
||||
/**
|
||||
Shuts down ENet globally. Should be called when a program that has
|
||||
initialized ENet exits.
|
||||
*/
|
||||
ENET_API void enet_deinitialize (void);
|
||||
|
||||
/**
|
||||
Gives the linked version of the ENet library.
|
||||
@returns the version number
|
||||
*/
|
||||
ENET_API ENetVersion enet_linked_version (void);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @defgroup private ENet private implementation functions */
|
||||
|
||||
/**
|
||||
Returns the wall-time in milliseconds. Its initial value is unspecified
|
||||
unless otherwise set.
|
||||
*/
|
||||
ENET_API enet_uint32 enet_time_get (void);
|
||||
/**
|
||||
Sets the current wall-time in milliseconds.
|
||||
*/
|
||||
ENET_API void enet_time_set (enet_uint32);
|
||||
|
||||
/** @defgroup socket ENet socket functions
|
||||
@{
|
||||
*/
|
||||
ENET_API ENetSocket enet_socket_create (ENetSocketType);
|
||||
ENET_API int enet_socket_bind (ENetSocket, const ENetAddress *);
|
||||
ENET_API int enet_socket_get_address (ENetSocket, ENetAddress *);
|
||||
ENET_API int enet_socket_listen (ENetSocket, int);
|
||||
ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *);
|
||||
ENET_API int enet_socket_connect (ENetSocket, const ENetAddress *);
|
||||
ENET_API int enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t);
|
||||
ENET_API int enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t);
|
||||
ENET_API int enet_socket_wait (ENetSocket, enet_uint32 *, enet_uint32);
|
||||
ENET_API int enet_socket_set_option (ENetSocket, ENetSocketOption, int);
|
||||
ENET_API int enet_socket_get_option (ENetSocket, ENetSocketOption, int *);
|
||||
ENET_API int enet_socket_shutdown (ENetSocket, ENetSocketShutdown);
|
||||
ENET_API void enet_socket_destroy (ENetSocket);
|
||||
ENET_API int enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSocketSet *, enet_uint32);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @defgroup Address ENet address functions
|
||||
@{
|
||||
*/
|
||||
|
||||
/** Attempts to parse the printable form of the IP address in the parameter hostName
|
||||
and sets the host field in the address parameter if successful.
|
||||
@param address destination to store the parsed IP address
|
||||
@param hostName IP address to parse
|
||||
@retval 0 on success
|
||||
@retval < 0 on failure
|
||||
@returns the address of the given hostName in address on success
|
||||
*/
|
||||
ENET_API int enet_address_set_host_ip (ENetAddress * address, const char * hostName);
|
||||
|
||||
/** Attempts to resolve the host named by the parameter hostName and sets
|
||||
the host field in the address parameter if successful.
|
||||
@param address destination to store resolved address
|
||||
@param hostName host name to lookup
|
||||
@retval 0 on success
|
||||
@retval < 0 on failure
|
||||
@returns the address of the given hostName in address on success
|
||||
*/
|
||||
ENET_API int enet_address_set_host (ENetAddress * address, const char * hostName);
|
||||
|
||||
/** Gives the printable form of the IP address specified in the address parameter.
|
||||
@param address address printed
|
||||
@param hostName destination for name, must not be NULL
|
||||
@param nameLength maximum length of hostName.
|
||||
@returns the null-terminated name of the host in hostName on success
|
||||
@retval 0 on success
|
||||
@retval < 0 on failure
|
||||
*/
|
||||
ENET_API int enet_address_get_host_ip (const ENetAddress * address, char * hostName, size_t nameLength);
|
||||
|
||||
/** Attempts to do a reverse lookup of the host field in the address parameter.
|
||||
@param address address used for reverse lookup
|
||||
@param hostName destination for name, must not be NULL
|
||||
@param nameLength maximum length of hostName.
|
||||
@returns the null-terminated name of the host in hostName on success
|
||||
@retval 0 on success
|
||||
@retval < 0 on failure
|
||||
*/
|
||||
ENET_API int enet_address_get_host (const ENetAddress * address, char * hostName, size_t nameLength);
|
||||
|
||||
/** @} */
|
||||
|
||||
ENET_API ENetPacket * enet_packet_create (const void *, size_t, enet_uint32);
|
||||
ENET_API void enet_packet_destroy (ENetPacket *);
|
||||
ENET_API int enet_packet_resize (ENetPacket *, size_t);
|
||||
ENET_API enet_uint32 enet_crc32 (const ENetBuffer *, size_t);
|
||||
|
||||
ENET_API ENetHost * enet_host_create (const ENetAddress *, size_t, size_t, enet_uint32, enet_uint32);
|
||||
ENET_API void enet_host_destroy (ENetHost *);
|
||||
ENET_API ENetPeer * enet_host_connect (ENetHost *, const ENetAddress *, size_t, enet_uint32);
|
||||
ENET_API int enet_host_check_events (ENetHost *, ENetEvent *);
|
||||
ENET_API int enet_host_service (ENetHost *, ENetEvent *, enet_uint32);
|
||||
ENET_API void enet_host_flush (ENetHost *);
|
||||
ENET_API void enet_host_broadcast (ENetHost *, enet_uint8, ENetPacket *);
|
||||
ENET_API void enet_host_compress (ENetHost *, const ENetCompressor *);
|
||||
ENET_API int enet_host_compress_with_range_coder (ENetHost * host);
|
||||
ENET_API void enet_host_channel_limit (ENetHost *, size_t);
|
||||
ENET_API void enet_host_bandwidth_limit (ENetHost *, enet_uint32, enet_uint32);
|
||||
extern void enet_host_bandwidth_throttle (ENetHost *);
|
||||
extern enet_uint32 enet_host_random_seed (void);
|
||||
extern enet_uint32 enet_host_random (ENetHost *);
|
||||
|
||||
ENET_API int enet_peer_send (ENetPeer *, enet_uint8, ENetPacket *);
|
||||
ENET_API ENetPacket * enet_peer_receive (ENetPeer *, enet_uint8 * channelID);
|
||||
ENET_API void enet_peer_ping (ENetPeer *);
|
||||
ENET_API void enet_peer_ping_interval (ENetPeer *, enet_uint32);
|
||||
ENET_API void enet_peer_timeout (ENetPeer *, enet_uint32, enet_uint32, enet_uint32);
|
||||
ENET_API void enet_peer_reset (ENetPeer *);
|
||||
ENET_API void enet_peer_disconnect (ENetPeer *, enet_uint32);
|
||||
ENET_API void enet_peer_disconnect_now (ENetPeer *, enet_uint32);
|
||||
ENET_API void enet_peer_disconnect_later (ENetPeer *, enet_uint32);
|
||||
ENET_API void enet_peer_throttle_configure (ENetPeer *, enet_uint32, enet_uint32, enet_uint32);
|
||||
extern int enet_peer_throttle (ENetPeer *, enet_uint32);
|
||||
extern void enet_peer_reset_queues (ENetPeer *);
|
||||
extern int enet_peer_has_outgoing_commands (ENetPeer *);
|
||||
extern void enet_peer_setup_outgoing_command (ENetPeer *, ENetOutgoingCommand *);
|
||||
extern ENetOutgoingCommand * enet_peer_queue_outgoing_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32, enet_uint16);
|
||||
extern ENetIncomingCommand * enet_peer_queue_incoming_command (ENetPeer *, const ENetProtocol *, const void *, size_t, enet_uint32, enet_uint32);
|
||||
extern ENetAcknowledgement * enet_peer_queue_acknowledgement (ENetPeer *, const ENetProtocol *, enet_uint16);
|
||||
extern void enet_peer_dispatch_incoming_unreliable_commands (ENetPeer *, ENetChannel *, ENetIncomingCommand *);
|
||||
extern void enet_peer_dispatch_incoming_reliable_commands (ENetPeer *, ENetChannel *, ENetIncomingCommand *);
|
||||
extern void enet_peer_on_connect (ENetPeer *);
|
||||
extern void enet_peer_on_disconnect (ENetPeer *);
|
||||
|
||||
ENET_API void * enet_range_coder_create (void);
|
||||
ENET_API void enet_range_coder_destroy (void *);
|
||||
ENET_API size_t enet_range_coder_compress (void *, const ENetBuffer *, size_t, size_t, enet_uint8 *, size_t);
|
||||
ENET_API size_t enet_range_coder_decompress (void *, const enet_uint8 *, size_t, enet_uint8 *, size_t);
|
||||
|
||||
extern size_t enet_protocol_command_size (enet_uint8);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ENET_ENET_H__ */
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
@file list.h
|
||||
@brief ENet list management
|
||||
*/
|
||||
#ifndef __ENET_LIST_H__
|
||||
#define __ENET_LIST_H__
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct _ENetListNode
|
||||
{
|
||||
struct _ENetListNode * next;
|
||||
struct _ENetListNode * previous;
|
||||
} ENetListNode;
|
||||
|
||||
typedef ENetListNode * ENetListIterator;
|
||||
|
||||
typedef struct _ENetList
|
||||
{
|
||||
ENetListNode sentinel;
|
||||
} ENetList;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
extern void enet_list_clear (ENetList *);
|
||||
|
||||
extern ENetListIterator enet_list_insert (ENetListIterator, void *);
|
||||
extern void * enet_list_remove (ENetListIterator);
|
||||
extern ENetListIterator enet_list_move (ENetListIterator, void *, void *);
|
||||
|
||||
extern size_t enet_list_size (ENetList *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define enet_list_begin(list) ((list) -> sentinel.next)
|
||||
#define enet_list_end(list) (& (list) -> sentinel)
|
||||
|
||||
#define enet_list_empty(list) (enet_list_begin (list) == enet_list_end (list))
|
||||
|
||||
#define enet_list_next(iterator) ((iterator) -> next)
|
||||
#define enet_list_previous(iterator) ((iterator) -> previous)
|
||||
|
||||
#define enet_list_front(list) ((void *) (list) -> sentinel.next)
|
||||
#define enet_list_back(list) ((void *) (list) -> sentinel.previous)
|
||||
|
||||
#endif /* __ENET_LIST_H__ */
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
/**
|
||||
@file protocol.h
|
||||
@brief ENet protocol
|
||||
*/
|
||||
#ifndef __ENET_PROTOCOL_H__
|
||||
#define __ENET_PROTOCOL_H__
|
||||
|
||||
#include "enet/types.h"
|
||||
|
||||
enum
|
||||
{
|
||||
ENET_PROTOCOL_MINIMUM_MTU = 576,
|
||||
ENET_PROTOCOL_MAXIMUM_MTU = 4096,
|
||||
ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS = 32,
|
||||
ENET_PROTOCOL_MINIMUM_WINDOW_SIZE = 4096,
|
||||
ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE = 65536,
|
||||
ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT = 1,
|
||||
ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT = 255,
|
||||
ENET_PROTOCOL_MAXIMUM_PEER_ID = 0xFFF,
|
||||
ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT = 1024 * 1024
|
||||
};
|
||||
|
||||
typedef enum _ENetProtocolCommand
|
||||
{
|
||||
ENET_PROTOCOL_COMMAND_NONE = 0,
|
||||
ENET_PROTOCOL_COMMAND_ACKNOWLEDGE = 1,
|
||||
ENET_PROTOCOL_COMMAND_CONNECT = 2,
|
||||
ENET_PROTOCOL_COMMAND_VERIFY_CONNECT = 3,
|
||||
ENET_PROTOCOL_COMMAND_DISCONNECT = 4,
|
||||
ENET_PROTOCOL_COMMAND_PING = 5,
|
||||
ENET_PROTOCOL_COMMAND_SEND_RELIABLE = 6,
|
||||
ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE = 7,
|
||||
ENET_PROTOCOL_COMMAND_SEND_FRAGMENT = 8,
|
||||
ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED = 9,
|
||||
ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT = 10,
|
||||
ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE = 11,
|
||||
ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT = 12,
|
||||
ENET_PROTOCOL_COMMAND_COUNT = 13,
|
||||
|
||||
ENET_PROTOCOL_COMMAND_MASK = 0x0F
|
||||
} ENetProtocolCommand;
|
||||
|
||||
typedef enum _ENetProtocolFlag
|
||||
{
|
||||
ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE = (1 << 7),
|
||||
ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED = (1 << 6),
|
||||
|
||||
ENET_PROTOCOL_HEADER_FLAG_COMPRESSED = (1 << 14),
|
||||
ENET_PROTOCOL_HEADER_FLAG_SENT_TIME = (1 << 15),
|
||||
ENET_PROTOCOL_HEADER_FLAG_MASK = ENET_PROTOCOL_HEADER_FLAG_COMPRESSED | ENET_PROTOCOL_HEADER_FLAG_SENT_TIME,
|
||||
|
||||
ENET_PROTOCOL_HEADER_SESSION_MASK = (3 << 12),
|
||||
ENET_PROTOCOL_HEADER_SESSION_SHIFT = 12
|
||||
} ENetProtocolFlag;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(push, 1)
|
||||
#define ENET_PACKED
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
#define ENET_PACKED __attribute__ ((packed))
|
||||
#else
|
||||
#define ENET_PACKED
|
||||
#endif
|
||||
|
||||
typedef struct _ENetProtocolHeader
|
||||
{
|
||||
enet_uint16 peerID;
|
||||
enet_uint16 sentTime;
|
||||
} ENET_PACKED ENetProtocolHeader;
|
||||
|
||||
typedef struct _ENetProtocolCommandHeader
|
||||
{
|
||||
enet_uint8 command;
|
||||
enet_uint8 channelID;
|
||||
enet_uint16 reliableSequenceNumber;
|
||||
} ENET_PACKED ENetProtocolCommandHeader;
|
||||
|
||||
typedef struct _ENetProtocolAcknowledge
|
||||
{
|
||||
ENetProtocolCommandHeader header;
|
||||
enet_uint16 receivedReliableSequenceNumber;
|
||||
enet_uint16 receivedSentTime;
|
||||
} ENET_PACKED ENetProtocolAcknowledge;
|
||||
|
||||
typedef struct _ENetProtocolConnect
|
||||
{
|
||||
ENetProtocolCommandHeader header;
|
||||
enet_uint16 outgoingPeerID;
|
||||
enet_uint8 incomingSessionID;
|
||||
enet_uint8 outgoingSessionID;
|
||||
enet_uint32 mtu;
|
||||
enet_uint32 windowSize;
|
||||
enet_uint32 channelCount;
|
||||
enet_uint32 incomingBandwidth;
|
||||
enet_uint32 outgoingBandwidth;
|
||||
enet_uint32 packetThrottleInterval;
|
||||
enet_uint32 packetThrottleAcceleration;
|
||||
enet_uint32 packetThrottleDeceleration;
|
||||
enet_uint32 connectID;
|
||||
enet_uint32 data;
|
||||
} ENET_PACKED ENetProtocolConnect;
|
||||
|
||||
typedef struct _ENetProtocolVerifyConnect
|
||||
{
|
||||
ENetProtocolCommandHeader header;
|
||||
enet_uint16 outgoingPeerID;
|
||||
enet_uint8 incomingSessionID;
|
||||
enet_uint8 outgoingSessionID;
|
||||
enet_uint32 mtu;
|
||||
enet_uint32 windowSize;
|
||||
enet_uint32 channelCount;
|
||||
enet_uint32 incomingBandwidth;
|
||||
enet_uint32 outgoingBandwidth;
|
||||
enet_uint32 packetThrottleInterval;
|
||||
enet_uint32 packetThrottleAcceleration;
|
||||
enet_uint32 packetThrottleDeceleration;
|
||||
enet_uint32 connectID;
|
||||
} ENET_PACKED ENetProtocolVerifyConnect;
|
||||
|
||||
typedef struct _ENetProtocolBandwidthLimit
|
||||
{
|
||||
ENetProtocolCommandHeader header;
|
||||
enet_uint32 incomingBandwidth;
|
||||
enet_uint32 outgoingBandwidth;
|
||||
} ENET_PACKED ENetProtocolBandwidthLimit;
|
||||
|
||||
typedef struct _ENetProtocolThrottleConfigure
|
||||
{
|
||||
ENetProtocolCommandHeader header;
|
||||
enet_uint32 packetThrottleInterval;
|
||||
enet_uint32 packetThrottleAcceleration;
|
||||
enet_uint32 packetThrottleDeceleration;
|
||||
} ENET_PACKED ENetProtocolThrottleConfigure;
|
||||
|
||||
typedef struct _ENetProtocolDisconnect
|
||||
{
|
||||
ENetProtocolCommandHeader header;
|
||||
enet_uint32 data;
|
||||
} ENET_PACKED ENetProtocolDisconnect;
|
||||
|
||||
typedef struct _ENetProtocolPing
|
||||
{
|
||||
ENetProtocolCommandHeader header;
|
||||
} ENET_PACKED ENetProtocolPing;
|
||||
|
||||
typedef struct _ENetProtocolSendReliable
|
||||
{
|
||||
ENetProtocolCommandHeader header;
|
||||
enet_uint16 dataLength;
|
||||
} ENET_PACKED ENetProtocolSendReliable;
|
||||
|
||||
typedef struct _ENetProtocolSendUnreliable
|
||||
{
|
||||
ENetProtocolCommandHeader header;
|
||||
enet_uint16 unreliableSequenceNumber;
|
||||
enet_uint16 dataLength;
|
||||
} ENET_PACKED ENetProtocolSendUnreliable;
|
||||
|
||||
typedef struct _ENetProtocolSendUnsequenced
|
||||
{
|
||||
ENetProtocolCommandHeader header;
|
||||
enet_uint16 unsequencedGroup;
|
||||
enet_uint16 dataLength;
|
||||
} ENET_PACKED ENetProtocolSendUnsequenced;
|
||||
|
||||
typedef struct _ENetProtocolSendFragment
|
||||
{
|
||||
ENetProtocolCommandHeader header;
|
||||
enet_uint16 startSequenceNumber;
|
||||
enet_uint16 dataLength;
|
||||
enet_uint32 fragmentCount;
|
||||
enet_uint32 fragmentNumber;
|
||||
enet_uint32 totalLength;
|
||||
enet_uint32 fragmentOffset;
|
||||
} ENET_PACKED ENetProtocolSendFragment;
|
||||
|
||||
typedef union _ENetProtocol
|
||||
{
|
||||
ENetProtocolCommandHeader header;
|
||||
ENetProtocolAcknowledge acknowledge;
|
||||
ENetProtocolConnect connect;
|
||||
ENetProtocolVerifyConnect verifyConnect;
|
||||
ENetProtocolDisconnect disconnect;
|
||||
ENetProtocolPing ping;
|
||||
ENetProtocolSendReliable sendReliable;
|
||||
ENetProtocolSendUnreliable sendUnreliable;
|
||||
ENetProtocolSendUnsequenced sendUnsequenced;
|
||||
ENetProtocolSendFragment sendFragment;
|
||||
ENetProtocolBandwidthLimit bandwidthLimit;
|
||||
ENetProtocolThrottleConfigure throttleConfigure;
|
||||
} ENET_PACKED ENetProtocol;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
#endif /* __ENET_PROTOCOL_H__ */
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
@file time.h
|
||||
@brief ENet time constants and macros
|
||||
*/
|
||||
#ifndef __ENET_TIME_H__
|
||||
#define __ENET_TIME_H__
|
||||
|
||||
#define ENET_TIME_OVERFLOW 86400000
|
||||
|
||||
#define ENET_TIME_LESS(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW)
|
||||
#define ENET_TIME_GREATER(a, b) ((b) - (a) >= ENET_TIME_OVERFLOW)
|
||||
#define ENET_TIME_LESS_EQUAL(a, b) (! ENET_TIME_GREATER (a, b))
|
||||
#define ENET_TIME_GREATER_EQUAL(a, b) (! ENET_TIME_LESS (a, b))
|
||||
|
||||
#define ENET_TIME_DIFFERENCE(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW ? (b) - (a) : (a) - (b))
|
||||
|
||||
#endif /* __ENET_TIME_H__ */
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
@file types.h
|
||||
@brief type definitions for ENet
|
||||
*/
|
||||
#ifndef __ENET_TYPES_H__
|
||||
#define __ENET_TYPES_H__
|
||||
|
||||
typedef unsigned char enet_uint8; /**< unsigned 8-bit type */
|
||||
typedef unsigned short enet_uint16; /**< unsigned 16-bit type */
|
||||
typedef unsigned int enet_uint32; /**< unsigned 32-bit type */
|
||||
|
||||
#endif /* __ENET_TYPES_H__ */
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
@file unix.h
|
||||
@brief ENet Unix header
|
||||
*/
|
||||
#ifndef __ENET_UNIX_H__
|
||||
#define __ENET_UNIX_H__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef MSG_MAXIOVLEN
|
||||
#define ENET_BUFFER_MAXIMUM MSG_MAXIOVLEN
|
||||
#endif
|
||||
|
||||
typedef int ENetSocket;
|
||||
|
||||
#define ENET_SOCKET_NULL -1
|
||||
|
||||
#define ENET_HOST_TO_NET_16(value) (htons (value)) /**< macro that converts host to net byte-order of a 16-bit value */
|
||||
#define ENET_HOST_TO_NET_32(value) (htonl (value)) /**< macro that converts host to net byte-order of a 32-bit value */
|
||||
|
||||
#define ENET_NET_TO_HOST_16(value) (ntohs (value)) /**< macro that converts net to host byte-order of a 16-bit value */
|
||||
#define ENET_NET_TO_HOST_32(value) (ntohl (value)) /**< macro that converts net to host byte-order of a 32-bit value */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void * data;
|
||||
size_t dataLength;
|
||||
} ENetBuffer;
|
||||
|
||||
#define ENET_CALLBACK
|
||||
|
||||
#define ENET_API extern
|
||||
|
||||
typedef fd_set ENetSocketSet;
|
||||
|
||||
#define ENET_SOCKETSET_EMPTY(sockset) FD_ZERO (& (sockset))
|
||||
#define ENET_SOCKETSET_ADD(sockset, socket) FD_SET (socket, & (sockset))
|
||||
#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLR (socket, & (sockset))
|
||||
#define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET (socket, & (sockset))
|
||||
|
||||
#endif /* __ENET_UNIX_H__ */
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
@file utility.h
|
||||
@brief ENet utility header
|
||||
*/
|
||||
#ifndef __ENET_UTILITY_H__
|
||||
#define __ENET_UTILITY_H__
|
||||
|
||||
#ifdef HAS_OFFSETOF
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
|
||||
#define ENET_MAX(x, y) ((x) > (y) ? (x) : (y))
|
||||
#define ENET_MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||
#define ENET_DIFFERENCE(x, y) ((x) < (y) ? (y) - (x) : (x) - (y))
|
||||
|
||||
#ifdef HAS_OFFSETOF
|
||||
#define ENET_OFFSETOF(str, field) (offsetof(str, field))
|
||||
#else
|
||||
#define ENET_OFFSETOF(str, field) ((size_t) & ((str *) 0) -> field)
|
||||
#endif
|
||||
|
||||
#endif /* __ENET_UTILITY_H__ */
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
@file win32.h
|
||||
@brief ENet Win32 header
|
||||
*/
|
||||
#ifndef __ENET_WIN32_H__
|
||||
#define __ENET_WIN32_H__
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifdef ENET_BUILDING_LIB
|
||||
#pragma warning (disable: 4267) // size_t to int conversion
|
||||
#pragma warning (disable: 4244) // 64bit to 32bit int
|
||||
#pragma warning (disable: 4018) // signed/unsigned mismatch
|
||||
#pragma warning (disable: 4146) // unary minus operator applied to unsigned type
|
||||
#ifndef _CRT_SECURE_NO_DEPRECATE
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#endif
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <winsock2.h>
|
||||
|
||||
typedef SOCKET ENetSocket;
|
||||
|
||||
#define ENET_SOCKET_NULL INVALID_SOCKET
|
||||
|
||||
#define ENET_HOST_TO_NET_16(value) (htons (value))
|
||||
#define ENET_HOST_TO_NET_32(value) (htonl (value))
|
||||
|
||||
#define ENET_NET_TO_HOST_16(value) (ntohs (value))
|
||||
#define ENET_NET_TO_HOST_32(value) (ntohl (value))
|
||||
|
||||
typedef struct
|
||||
{
|
||||
size_t dataLength;
|
||||
void * data;
|
||||
} ENetBuffer;
|
||||
|
||||
#define ENET_CALLBACK __cdecl
|
||||
|
||||
#ifdef ENET_DLL
|
||||
#ifdef ENET_BUILDING_LIB
|
||||
#define ENET_API __declspec( dllexport )
|
||||
#else
|
||||
#define ENET_API __declspec( dllimport )
|
||||
#endif /* ENET_BUILDING_LIB */
|
||||
#else /* !ENET_DLL */
|
||||
#define ENET_API extern
|
||||
#endif /* ENET_DLL */
|
||||
|
||||
typedef fd_set ENetSocketSet;
|
||||
|
||||
#define ENET_SOCKETSET_EMPTY(sockset) FD_ZERO (& (sockset))
|
||||
#define ENET_SOCKETSET_ADD(sockset, socket) FD_SET (socket, & (sockset))
|
||||
#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLR (socket, & (sockset))
|
||||
#define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET (socket, & (sockset))
|
||||
|
||||
#endif /* __ENET_WIN32_H__ */
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: @PACKAGE_NAME@
|
||||
Description: Low-latency UDP networking library supporting optional reliability
|
||||
Version: @PACKAGE_VERSION@
|
||||
Cflags: -I${includedir}
|
||||
Libs: -L${libdir} -lenet
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
@file list.c
|
||||
@brief ENet linked list functions
|
||||
*/
|
||||
#define ENET_BUILDING_LIB 1
|
||||
#include "enet/enet.h"
|
||||
|
||||
/**
|
||||
@defgroup list ENet linked list utility functions
|
||||
@ingroup private
|
||||
@{
|
||||
*/
|
||||
void
|
||||
enet_list_clear (ENetList * list)
|
||||
{
|
||||
list -> sentinel.next = & list -> sentinel;
|
||||
list -> sentinel.previous = & list -> sentinel;
|
||||
}
|
||||
|
||||
ENetListIterator
|
||||
enet_list_insert (ENetListIterator position, void * data)
|
||||
{
|
||||
ENetListIterator result = (ENetListIterator) data;
|
||||
|
||||
result -> previous = position -> previous;
|
||||
result -> next = position;
|
||||
|
||||
result -> previous -> next = result;
|
||||
position -> previous = result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void *
|
||||
enet_list_remove (ENetListIterator position)
|
||||
{
|
||||
position -> previous -> next = position -> next;
|
||||
position -> next -> previous = position -> previous;
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
ENetListIterator
|
||||
enet_list_move (ENetListIterator position, void * dataFirst, void * dataLast)
|
||||
{
|
||||
ENetListIterator first = (ENetListIterator) dataFirst,
|
||||
last = (ENetListIterator) dataLast;
|
||||
|
||||
first -> previous -> next = last -> next;
|
||||
last -> next -> previous = first -> previous;
|
||||
|
||||
first -> previous = position -> previous;
|
||||
last -> next = position;
|
||||
|
||||
first -> previous -> next = first;
|
||||
position -> previous = last;
|
||||
|
||||
return first;
|
||||
}
|
||||
|
||||
size_t
|
||||
enet_list_size (ENetList * list)
|
||||
{
|
||||
size_t size = 0;
|
||||
ENetListIterator position;
|
||||
|
||||
for (position = enet_list_begin (list);
|
||||
position != enet_list_end (list);
|
||||
position = enet_list_next (position))
|
||||
++ size;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
@@ -0,0 +1,163 @@
|
||||
/**
|
||||
@file packet.c
|
||||
@brief ENet packet management functions
|
||||
*/
|
||||
#include <string.h>
|
||||
#define ENET_BUILDING_LIB 1
|
||||
#include "enet/enet.h"
|
||||
|
||||
/** @defgroup Packet ENet packet functions
|
||||
@{
|
||||
*/
|
||||
|
||||
/** Creates a packet that may be sent to a peer.
|
||||
@param data initial contents of the packet's data; the packet's data will remain uninitialized if data is NULL.
|
||||
@param dataLength size of the data allocated for this packet
|
||||
@param flags flags for this packet as described for the ENetPacket structure.
|
||||
@returns the packet on success, NULL on failure
|
||||
*/
|
||||
ENetPacket *
|
||||
enet_packet_create (const void * data, size_t dataLength, enet_uint32 flags)
|
||||
{
|
||||
ENetPacket * packet = (ENetPacket *) enet_malloc (sizeof (ENetPacket));
|
||||
if (packet == NULL)
|
||||
return NULL;
|
||||
|
||||
if (flags & ENET_PACKET_FLAG_NO_ALLOCATE)
|
||||
packet -> data = (enet_uint8 *) data;
|
||||
else
|
||||
if (dataLength <= 0)
|
||||
packet -> data = NULL;
|
||||
else
|
||||
{
|
||||
packet -> data = (enet_uint8 *) enet_malloc (dataLength);
|
||||
if (packet -> data == NULL)
|
||||
{
|
||||
enet_free (packet);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (data != NULL)
|
||||
memcpy (packet -> data, data, dataLength);
|
||||
}
|
||||
|
||||
packet -> referenceCount = 0;
|
||||
packet -> flags = flags;
|
||||
packet -> dataLength = dataLength;
|
||||
packet -> freeCallback = NULL;
|
||||
packet -> userData = NULL;
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
||||
/** Destroys the packet and deallocates its data.
|
||||
@param packet packet to be destroyed
|
||||
*/
|
||||
void
|
||||
enet_packet_destroy (ENetPacket * packet)
|
||||
{
|
||||
if (packet == NULL)
|
||||
return;
|
||||
|
||||
if (packet -> freeCallback != NULL)
|
||||
(* packet -> freeCallback) (packet);
|
||||
if (! (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE) &&
|
||||
packet -> data != NULL)
|
||||
enet_free (packet -> data);
|
||||
enet_free (packet);
|
||||
}
|
||||
|
||||
/** Attempts to resize the data in the packet to length specified in the
|
||||
dataLength parameter
|
||||
@param packet packet to resize
|
||||
@param dataLength new size for the packet data
|
||||
@returns 0 on success, < 0 on failure
|
||||
*/
|
||||
int
|
||||
enet_packet_resize (ENetPacket * packet, size_t dataLength)
|
||||
{
|
||||
enet_uint8 * newData;
|
||||
|
||||
if (dataLength <= packet -> dataLength || (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE))
|
||||
{
|
||||
packet -> dataLength = dataLength;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
newData = (enet_uint8 *) enet_malloc (dataLength);
|
||||
if (newData == NULL)
|
||||
return -1;
|
||||
|
||||
if (packet -> data != NULL)
|
||||
{
|
||||
if (packet -> dataLength > 0)
|
||||
memcpy (newData, packet -> data, packet -> dataLength);
|
||||
|
||||
enet_free (packet -> data);
|
||||
}
|
||||
|
||||
packet -> data = newData;
|
||||
packet -> dataLength = dataLength;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const enet_uint32 crcTable [256] =
|
||||
{
|
||||
0, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
|
||||
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
|
||||
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
|
||||
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
|
||||
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
|
||||
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
|
||||
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
|
||||
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
|
||||
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
|
||||
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
|
||||
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
|
||||
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
|
||||
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
|
||||
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
|
||||
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
|
||||
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
|
||||
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
|
||||
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
|
||||
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
|
||||
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
|
||||
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
|
||||
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
|
||||
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
|
||||
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
|
||||
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x5005713,
|
||||
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0xBDBDF21,
|
||||
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
|
||||
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
|
||||
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
|
||||
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
|
||||
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
|
||||
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
|
||||
};
|
||||
|
||||
enet_uint32
|
||||
enet_crc32 (const ENetBuffer * buffers, size_t bufferCount)
|
||||
{
|
||||
enet_uint32 crc = 0xFFFFFFFF;
|
||||
|
||||
while (bufferCount -- > 0)
|
||||
{
|
||||
const enet_uint8 * data = (const enet_uint8 *) buffers -> data,
|
||||
* dataEnd = & data [buffers -> dataLength];
|
||||
|
||||
while (data < dataEnd)
|
||||
{
|
||||
crc = (crc >> 8) ^ crcTable [(crc & 0xFF) ^ *data++];
|
||||
}
|
||||
|
||||
++ buffers;
|
||||
}
|
||||
|
||||
return ENET_HOST_TO_NET_32 (~ crc);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
+1030
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,59 @@
|
||||
solution "enet"
|
||||
configurations { "Debug", "Release" }
|
||||
platforms { "x32", "x64" }
|
||||
|
||||
project "enet_static"
|
||||
kind "StaticLib"
|
||||
language "C"
|
||||
|
||||
files { "*.c" }
|
||||
|
||||
includedirs { "include/" }
|
||||
|
||||
configuration "Debug"
|
||||
targetsuffix "d"
|
||||
|
||||
defines({ "DEBUG" })
|
||||
|
||||
flags { "Symbols" }
|
||||
|
||||
configuration "Release"
|
||||
defines({ "NDEBUG" })
|
||||
|
||||
flags { "Optimize" }
|
||||
|
||||
configuration { "Debug", "x64" }
|
||||
targetsuffix "64d"
|
||||
|
||||
configuration { "Release", "x64" }
|
||||
targetsuffix "64"
|
||||
|
||||
project "enet"
|
||||
kind "SharedLib"
|
||||
language "C"
|
||||
|
||||
files { "*.c" }
|
||||
|
||||
includedirs { "include/" }
|
||||
|
||||
defines({"ENET_DLL=1" })
|
||||
|
||||
configuration "Debug"
|
||||
targetsuffix "d"
|
||||
|
||||
defines({ "DEBUG" })
|
||||
|
||||
flags { "Symbols" }
|
||||
|
||||
configuration "Release"
|
||||
defines({ "NDEBUG" })
|
||||
|
||||
flags { "Optimize" }
|
||||
|
||||
configuration { "Debug", "x64" }
|
||||
targetsuffix "64d"
|
||||
|
||||
configuration { "Release", "x64" }
|
||||
targetsuffix "64"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,630 @@
|
||||
/**
|
||||
@file unix.c
|
||||
@brief ENet Unix system specific functions
|
||||
*/
|
||||
#ifndef _WIN32
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
|
||||
#define ENET_BUILDING_LIB 1
|
||||
#include "enet/enet.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#ifdef HAS_POLL
|
||||
#undef HAS_POLL
|
||||
#endif
|
||||
#ifndef HAS_FCNTL
|
||||
#define HAS_FCNTL 1
|
||||
#endif
|
||||
#ifndef HAS_INET_PTON
|
||||
#define HAS_INET_PTON 1
|
||||
#endif
|
||||
#ifndef HAS_INET_NTOP
|
||||
#define HAS_INET_NTOP 1
|
||||
#endif
|
||||
#ifndef HAS_MSGHDR_FLAGS
|
||||
#define HAS_MSGHDR_FLAGS 1
|
||||
#endif
|
||||
#ifndef HAS_SOCKLEN_T
|
||||
#define HAS_SOCKLEN_T 1
|
||||
#endif
|
||||
#ifndef HAS_GETADDRINFO
|
||||
#define HAS_GETADDRINFO 1
|
||||
#endif
|
||||
#ifndef HAS_GETNAMEINFO
|
||||
#define HAS_GETNAMEINFO 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAS_FCNTL
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAS_POLL
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
#if !defined(HAS_SOCKLEN_T) && !defined(__socklen_t_defined)
|
||||
typedef int socklen_t;
|
||||
#endif
|
||||
|
||||
#ifndef MSG_NOSIGNAL
|
||||
#define MSG_NOSIGNAL 0
|
||||
#endif
|
||||
|
||||
static enet_uint32 timeBase = 0;
|
||||
|
||||
int
|
||||
enet_initialize (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
enet_deinitialize (void)
|
||||
{
|
||||
}
|
||||
|
||||
enet_uint32
|
||||
enet_host_random_seed (void)
|
||||
{
|
||||
return (enet_uint32) time (NULL);
|
||||
}
|
||||
|
||||
enet_uint32
|
||||
enet_time_get (void)
|
||||
{
|
||||
struct timeval timeVal;
|
||||
|
||||
gettimeofday (& timeVal, NULL);
|
||||
|
||||
return timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - timeBase;
|
||||
}
|
||||
|
||||
void
|
||||
enet_time_set (enet_uint32 newTimeBase)
|
||||
{
|
||||
struct timeval timeVal;
|
||||
|
||||
gettimeofday (& timeVal, NULL);
|
||||
|
||||
timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase;
|
||||
}
|
||||
|
||||
int
|
||||
enet_address_set_host_ip (ENetAddress * address, const char * name)
|
||||
{
|
||||
#ifdef HAS_INET_PTON
|
||||
if (! inet_pton (AF_INET, name, & address -> host))
|
||||
#else
|
||||
if (! inet_aton (name, (struct in_addr *) & address -> host))
|
||||
#endif
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
enet_address_set_host (ENetAddress * address, const char * name)
|
||||
{
|
||||
#ifdef HAS_GETADDRINFO
|
||||
struct addrinfo hints, * resultList = NULL, * result = NULL;
|
||||
|
||||
memset (& hints, 0, sizeof (hints));
|
||||
hints.ai_family = AF_INET;
|
||||
|
||||
if (getaddrinfo (name, NULL, NULL, & resultList) != 0)
|
||||
return -1;
|
||||
|
||||
for (result = resultList; result != NULL; result = result -> ai_next)
|
||||
{
|
||||
if (result -> ai_family == AF_INET && result -> ai_addr != NULL && result -> ai_addrlen >= sizeof (struct sockaddr_in))
|
||||
{
|
||||
struct sockaddr_in * sin = (struct sockaddr_in *) result -> ai_addr;
|
||||
|
||||
address -> host = sin -> sin_addr.s_addr;
|
||||
|
||||
freeaddrinfo (resultList);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (resultList != NULL)
|
||||
freeaddrinfo (resultList);
|
||||
#else
|
||||
struct hostent * hostEntry = NULL;
|
||||
#ifdef HAS_GETHOSTBYNAME_R
|
||||
struct hostent hostData;
|
||||
char buffer [2048];
|
||||
int errnum;
|
||||
|
||||
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) || defined(__GNU__)
|
||||
gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
|
||||
#else
|
||||
hostEntry = gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & errnum);
|
||||
#endif
|
||||
#else
|
||||
hostEntry = gethostbyname (name);
|
||||
#endif
|
||||
|
||||
if (hostEntry != NULL && hostEntry -> h_addrtype == AF_INET)
|
||||
{
|
||||
address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return enet_address_set_host_ip (address, name);
|
||||
}
|
||||
|
||||
int
|
||||
enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
|
||||
{
|
||||
#ifdef HAS_INET_NTOP
|
||||
if (inet_ntop (AF_INET, & address -> host, name, nameLength) == NULL)
|
||||
#else
|
||||
char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
|
||||
if (addr != NULL)
|
||||
{
|
||||
size_t addrLen = strlen(addr);
|
||||
if (addrLen >= nameLength)
|
||||
return -1;
|
||||
memcpy (name, addr, addrLen + 1);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
|
||||
{
|
||||
#ifdef HAS_GETNAMEINFO
|
||||
struct sockaddr_in sin;
|
||||
int err;
|
||||
|
||||
memset (& sin, 0, sizeof (struct sockaddr_in));
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
|
||||
sin.sin_addr.s_addr = address -> host;
|
||||
|
||||
err = getnameinfo ((struct sockaddr *) & sin, sizeof (sin), name, nameLength, NULL, 0, NI_NAMEREQD);
|
||||
if (! err)
|
||||
{
|
||||
if (name != NULL && nameLength > 0 && ! memchr (name, '\0', nameLength))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
if (err != EAI_NONAME)
|
||||
return -1;
|
||||
#else
|
||||
struct in_addr in;
|
||||
struct hostent * hostEntry = NULL;
|
||||
#ifdef HAS_GETHOSTBYADDR_R
|
||||
struct hostent hostData;
|
||||
char buffer [2048];
|
||||
int errnum;
|
||||
|
||||
in.s_addr = address -> host;
|
||||
|
||||
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) || defined(__GNU__)
|
||||
gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
|
||||
#else
|
||||
hostEntry = gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & errnum);
|
||||
#endif
|
||||
#else
|
||||
in.s_addr = address -> host;
|
||||
|
||||
hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
|
||||
#endif
|
||||
|
||||
if (hostEntry != NULL)
|
||||
{
|
||||
size_t hostLen = strlen (hostEntry -> h_name);
|
||||
if (hostLen >= nameLength)
|
||||
return -1;
|
||||
memcpy (name, hostEntry -> h_name, hostLen + 1);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return enet_address_get_host_ip (address, name, nameLength);
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_bind (ENetSocket socket, const ENetAddress * address)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
|
||||
memset (& sin, 0, sizeof (struct sockaddr_in));
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
|
||||
if (address != NULL)
|
||||
{
|
||||
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
|
||||
sin.sin_addr.s_addr = address -> host;
|
||||
}
|
||||
else
|
||||
{
|
||||
sin.sin_port = 0;
|
||||
sin.sin_addr.s_addr = INADDR_ANY;
|
||||
}
|
||||
|
||||
return bind (socket,
|
||||
(struct sockaddr *) & sin,
|
||||
sizeof (struct sockaddr_in));
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_get_address (ENetSocket socket, ENetAddress * address)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
socklen_t sinLength = sizeof (struct sockaddr_in);
|
||||
|
||||
if (getsockname (socket, (struct sockaddr *) & sin, & sinLength) == -1)
|
||||
return -1;
|
||||
|
||||
address -> host = (enet_uint32) sin.sin_addr.s_addr;
|
||||
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_listen (ENetSocket socket, int backlog)
|
||||
{
|
||||
return listen (socket, backlog < 0 ? SOMAXCONN : backlog);
|
||||
}
|
||||
|
||||
ENetSocket
|
||||
enet_socket_create (ENetSocketType type)
|
||||
{
|
||||
return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
|
||||
{
|
||||
int result = -1;
|
||||
switch (option)
|
||||
{
|
||||
case ENET_SOCKOPT_NONBLOCK:
|
||||
#ifdef HAS_FCNTL
|
||||
result = fcntl (socket, F_SETFL, (value ? O_NONBLOCK : 0) | (fcntl (socket, F_GETFL) & ~O_NONBLOCK));
|
||||
#else
|
||||
result = ioctl (socket, FIONBIO, & value);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case ENET_SOCKOPT_BROADCAST:
|
||||
result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
|
||||
break;
|
||||
|
||||
case ENET_SOCKOPT_REUSEADDR:
|
||||
result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
|
||||
break;
|
||||
|
||||
case ENET_SOCKOPT_RCVBUF:
|
||||
result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int));
|
||||
break;
|
||||
|
||||
case ENET_SOCKOPT_SNDBUF:
|
||||
result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
|
||||
break;
|
||||
|
||||
case ENET_SOCKOPT_RCVTIMEO:
|
||||
{
|
||||
struct timeval timeVal;
|
||||
timeVal.tv_sec = value / 1000;
|
||||
timeVal.tv_usec = (value % 1000) * 1000;
|
||||
result = setsockopt (socket, SOL_SOCKET, SO_RCVTIMEO, (char *) & timeVal, sizeof (struct timeval));
|
||||
break;
|
||||
}
|
||||
|
||||
case ENET_SOCKOPT_SNDTIMEO:
|
||||
{
|
||||
struct timeval timeVal;
|
||||
timeVal.tv_sec = value / 1000;
|
||||
timeVal.tv_usec = (value % 1000) * 1000;
|
||||
result = setsockopt (socket, SOL_SOCKET, SO_SNDTIMEO, (char *) & timeVal, sizeof (struct timeval));
|
||||
break;
|
||||
}
|
||||
|
||||
case ENET_SOCKOPT_NODELAY:
|
||||
result = setsockopt (socket, IPPROTO_TCP, TCP_NODELAY, (char *) & value, sizeof (int));
|
||||
break;
|
||||
|
||||
case ENET_SOCKOPT_TTL:
|
||||
result = setsockopt (socket, IPPROTO_IP, IP_TTL, (char *) & value, sizeof (int));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result == -1 ? -1 : 0;
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_get_option (ENetSocket socket, ENetSocketOption option, int * value)
|
||||
{
|
||||
int result = -1;
|
||||
socklen_t len;
|
||||
switch (option)
|
||||
{
|
||||
case ENET_SOCKOPT_ERROR:
|
||||
len = sizeof (int);
|
||||
result = getsockopt (socket, SOL_SOCKET, SO_ERROR, value, & len);
|
||||
break;
|
||||
|
||||
case ENET_SOCKOPT_TTL:
|
||||
len = sizeof (int);
|
||||
result = getsockopt (socket, IPPROTO_IP, IP_TTL, (char *) value, & len);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result == -1 ? -1 : 0;
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_connect (ENetSocket socket, const ENetAddress * address)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
int result;
|
||||
|
||||
memset (& sin, 0, sizeof (struct sockaddr_in));
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
|
||||
sin.sin_addr.s_addr = address -> host;
|
||||
|
||||
result = connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
|
||||
if (result == -1 && errno == EINPROGRESS)
|
||||
return 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ENetSocket
|
||||
enet_socket_accept (ENetSocket socket, ENetAddress * address)
|
||||
{
|
||||
int result;
|
||||
struct sockaddr_in sin;
|
||||
socklen_t sinLength = sizeof (struct sockaddr_in);
|
||||
|
||||
result = accept (socket,
|
||||
address != NULL ? (struct sockaddr *) & sin : NULL,
|
||||
address != NULL ? & sinLength : NULL);
|
||||
|
||||
if (result == -1)
|
||||
return ENET_SOCKET_NULL;
|
||||
|
||||
if (address != NULL)
|
||||
{
|
||||
address -> host = (enet_uint32) sin.sin_addr.s_addr;
|
||||
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_shutdown (ENetSocket socket, ENetSocketShutdown how)
|
||||
{
|
||||
return shutdown (socket, (int) how);
|
||||
}
|
||||
|
||||
void
|
||||
enet_socket_destroy (ENetSocket socket)
|
||||
{
|
||||
if (socket != -1)
|
||||
close (socket);
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_send (ENetSocket socket,
|
||||
const ENetAddress * address,
|
||||
const ENetBuffer * buffers,
|
||||
size_t bufferCount)
|
||||
{
|
||||
struct msghdr msgHdr;
|
||||
struct sockaddr_in sin;
|
||||
int sentLength;
|
||||
|
||||
memset (& msgHdr, 0, sizeof (struct msghdr));
|
||||
|
||||
if (address != NULL)
|
||||
{
|
||||
memset (& sin, 0, sizeof (struct sockaddr_in));
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
|
||||
sin.sin_addr.s_addr = address -> host;
|
||||
|
||||
msgHdr.msg_name = & sin;
|
||||
msgHdr.msg_namelen = sizeof (struct sockaddr_in);
|
||||
}
|
||||
|
||||
msgHdr.msg_iov = (struct iovec *) buffers;
|
||||
msgHdr.msg_iovlen = bufferCount;
|
||||
|
||||
sentLength = sendmsg (socket, & msgHdr, MSG_NOSIGNAL);
|
||||
|
||||
if (sentLength == -1)
|
||||
{
|
||||
if (errno == EWOULDBLOCK)
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sentLength;
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_receive (ENetSocket socket,
|
||||
ENetAddress * address,
|
||||
ENetBuffer * buffers,
|
||||
size_t bufferCount)
|
||||
{
|
||||
struct msghdr msgHdr;
|
||||
struct sockaddr_in sin;
|
||||
int recvLength;
|
||||
|
||||
memset (& msgHdr, 0, sizeof (struct msghdr));
|
||||
|
||||
if (address != NULL)
|
||||
{
|
||||
msgHdr.msg_name = & sin;
|
||||
msgHdr.msg_namelen = sizeof (struct sockaddr_in);
|
||||
}
|
||||
|
||||
msgHdr.msg_iov = (struct iovec *) buffers;
|
||||
msgHdr.msg_iovlen = bufferCount;
|
||||
|
||||
recvLength = recvmsg (socket, & msgHdr, MSG_NOSIGNAL);
|
||||
|
||||
if (recvLength == -1)
|
||||
{
|
||||
switch (errno)
|
||||
{
|
||||
case EWOULDBLOCK:
|
||||
return 0;
|
||||
case EINTR:
|
||||
case EMSGSIZE:
|
||||
return -2;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAS_MSGHDR_FLAGS
|
||||
if (msgHdr.msg_flags & MSG_TRUNC)
|
||||
return -2;
|
||||
#endif
|
||||
|
||||
if (address != NULL)
|
||||
{
|
||||
address -> host = (enet_uint32) sin.sin_addr.s_addr;
|
||||
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
|
||||
}
|
||||
|
||||
return recvLength;
|
||||
}
|
||||
|
||||
int
|
||||
enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout)
|
||||
{
|
||||
struct timeval timeVal;
|
||||
|
||||
timeVal.tv_sec = timeout / 1000;
|
||||
timeVal.tv_usec = (timeout % 1000) * 1000;
|
||||
|
||||
return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal);
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
|
||||
{
|
||||
#ifdef HAS_POLL
|
||||
struct pollfd pollSocket;
|
||||
int pollCount;
|
||||
|
||||
pollSocket.fd = socket;
|
||||
pollSocket.events = 0;
|
||||
|
||||
if (* condition & ENET_SOCKET_WAIT_SEND)
|
||||
pollSocket.events |= POLLOUT;
|
||||
|
||||
if (* condition & ENET_SOCKET_WAIT_RECEIVE)
|
||||
pollSocket.events |= POLLIN;
|
||||
|
||||
pollCount = poll (& pollSocket, 1, timeout);
|
||||
|
||||
if (pollCount < 0)
|
||||
{
|
||||
if (errno == EINTR && * condition & ENET_SOCKET_WAIT_INTERRUPT)
|
||||
{
|
||||
* condition = ENET_SOCKET_WAIT_INTERRUPT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
* condition = ENET_SOCKET_WAIT_NONE;
|
||||
|
||||
if (pollCount == 0)
|
||||
return 0;
|
||||
|
||||
if (pollSocket.revents & POLLOUT)
|
||||
* condition |= ENET_SOCKET_WAIT_SEND;
|
||||
|
||||
if (pollSocket.revents & POLLIN)
|
||||
* condition |= ENET_SOCKET_WAIT_RECEIVE;
|
||||
|
||||
return 0;
|
||||
#else
|
||||
fd_set readSet, writeSet;
|
||||
struct timeval timeVal;
|
||||
int selectCount;
|
||||
|
||||
timeVal.tv_sec = timeout / 1000;
|
||||
timeVal.tv_usec = (timeout % 1000) * 1000;
|
||||
|
||||
FD_ZERO (& readSet);
|
||||
FD_ZERO (& writeSet);
|
||||
|
||||
if (* condition & ENET_SOCKET_WAIT_SEND)
|
||||
FD_SET (socket, & writeSet);
|
||||
|
||||
if (* condition & ENET_SOCKET_WAIT_RECEIVE)
|
||||
FD_SET (socket, & readSet);
|
||||
|
||||
selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
|
||||
|
||||
if (selectCount < 0)
|
||||
{
|
||||
if (errno == EINTR && * condition & ENET_SOCKET_WAIT_INTERRUPT)
|
||||
{
|
||||
* condition = ENET_SOCKET_WAIT_INTERRUPT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
* condition = ENET_SOCKET_WAIT_NONE;
|
||||
|
||||
if (selectCount == 0)
|
||||
return 0;
|
||||
|
||||
if (FD_ISSET (socket, & writeSet))
|
||||
* condition |= ENET_SOCKET_WAIT_SEND;
|
||||
|
||||
if (FD_ISSET (socket, & readSet))
|
||||
* condition |= ENET_SOCKET_WAIT_RECEIVE;
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,455 @@
|
||||
/**
|
||||
@file win32.c
|
||||
@brief ENet Win32 system specific functions
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
|
||||
#define ENET_BUILDING_LIB 1
|
||||
#include "enet/enet.h"
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
static enet_uint32 timeBase = 0;
|
||||
|
||||
int
|
||||
enet_initialize (void)
|
||||
{
|
||||
WORD versionRequested = MAKEWORD (1, 1);
|
||||
WSADATA wsaData;
|
||||
|
||||
if (WSAStartup (versionRequested, & wsaData))
|
||||
return -1;
|
||||
|
||||
if (LOBYTE (wsaData.wVersion) != 1||
|
||||
HIBYTE (wsaData.wVersion) != 1)
|
||||
{
|
||||
WSACleanup ();
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
timeBeginPeriod (1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
enet_deinitialize (void)
|
||||
{
|
||||
timeEndPeriod (1);
|
||||
|
||||
WSACleanup ();
|
||||
}
|
||||
|
||||
enet_uint32
|
||||
enet_host_random_seed (void)
|
||||
{
|
||||
return (enet_uint32) timeGetTime ();
|
||||
}
|
||||
|
||||
enet_uint32
|
||||
enet_time_get (void)
|
||||
{
|
||||
return (enet_uint32) timeGetTime () - timeBase;
|
||||
}
|
||||
|
||||
void
|
||||
enet_time_set (enet_uint32 newTimeBase)
|
||||
{
|
||||
timeBase = (enet_uint32) timeGetTime () - newTimeBase;
|
||||
}
|
||||
|
||||
int
|
||||
enet_address_set_host_ip (ENetAddress * address, const char * name)
|
||||
{
|
||||
enet_uint8 vals [4] = { 0, 0, 0, 0 };
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; ++ i)
|
||||
{
|
||||
const char * next = name + 1;
|
||||
if (* name != '0')
|
||||
{
|
||||
long val = strtol (name, (char **) & next, 10);
|
||||
if (val < 0 || val > 255 || next == name || next - name > 3)
|
||||
return -1;
|
||||
vals [i] = (enet_uint8) val;
|
||||
}
|
||||
|
||||
if (* next != (i < 3 ? '.' : '\0'))
|
||||
return -1;
|
||||
name = next + 1;
|
||||
}
|
||||
|
||||
memcpy (& address -> host, vals, sizeof (enet_uint32));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
enet_address_set_host (ENetAddress * address, const char * name)
|
||||
{
|
||||
struct hostent * hostEntry;
|
||||
|
||||
hostEntry = gethostbyname (name);
|
||||
if (hostEntry == NULL ||
|
||||
hostEntry -> h_addrtype != AF_INET)
|
||||
return enet_address_set_host_ip (address, name);
|
||||
|
||||
address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
|
||||
{
|
||||
char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
|
||||
if (addr == NULL)
|
||||
return -1;
|
||||
else
|
||||
{
|
||||
size_t addrLen = strlen(addr);
|
||||
if (addrLen >= nameLength)
|
||||
return -1;
|
||||
memcpy (name, addr, addrLen + 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
|
||||
{
|
||||
struct in_addr in;
|
||||
struct hostent * hostEntry;
|
||||
|
||||
in.s_addr = address -> host;
|
||||
|
||||
hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
|
||||
if (hostEntry == NULL)
|
||||
return enet_address_get_host_ip (address, name, nameLength);
|
||||
else
|
||||
{
|
||||
size_t hostLen = strlen (hostEntry -> h_name);
|
||||
if (hostLen >= nameLength)
|
||||
return -1;
|
||||
memcpy (name, hostEntry -> h_name, hostLen + 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_bind (ENetSocket socket, const ENetAddress * address)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
|
||||
memset (& sin, 0, sizeof (struct sockaddr_in));
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
|
||||
if (address != NULL)
|
||||
{
|
||||
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
|
||||
sin.sin_addr.s_addr = address -> host;
|
||||
}
|
||||
else
|
||||
{
|
||||
sin.sin_port = 0;
|
||||
sin.sin_addr.s_addr = INADDR_ANY;
|
||||
}
|
||||
|
||||
return bind (socket,
|
||||
(struct sockaddr *) & sin,
|
||||
sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_get_address (ENetSocket socket, ENetAddress * address)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
int sinLength = sizeof (struct sockaddr_in);
|
||||
|
||||
if (getsockname (socket, (struct sockaddr *) & sin, & sinLength) == -1)
|
||||
return -1;
|
||||
|
||||
address -> host = (enet_uint32) sin.sin_addr.s_addr;
|
||||
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_listen (ENetSocket socket, int backlog)
|
||||
{
|
||||
return listen (socket, backlog < 0 ? SOMAXCONN : backlog) == SOCKET_ERROR ? -1 : 0;
|
||||
}
|
||||
|
||||
ENetSocket
|
||||
enet_socket_create (ENetSocketType type)
|
||||
{
|
||||
return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
|
||||
{
|
||||
int result = SOCKET_ERROR;
|
||||
switch (option)
|
||||
{
|
||||
case ENET_SOCKOPT_NONBLOCK:
|
||||
{
|
||||
u_long nonBlocking = (u_long) value;
|
||||
result = ioctlsocket (socket, FIONBIO, & nonBlocking);
|
||||
break;
|
||||
}
|
||||
|
||||
case ENET_SOCKOPT_BROADCAST:
|
||||
result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
|
||||
break;
|
||||
|
||||
case ENET_SOCKOPT_REUSEADDR:
|
||||
result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
|
||||
break;
|
||||
|
||||
case ENET_SOCKOPT_RCVBUF:
|
||||
result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int));
|
||||
break;
|
||||
|
||||
case ENET_SOCKOPT_SNDBUF:
|
||||
result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
|
||||
break;
|
||||
|
||||
case ENET_SOCKOPT_RCVTIMEO:
|
||||
result = setsockopt (socket, SOL_SOCKET, SO_RCVTIMEO, (char *) & value, sizeof (int));
|
||||
break;
|
||||
|
||||
case ENET_SOCKOPT_SNDTIMEO:
|
||||
result = setsockopt (socket, SOL_SOCKET, SO_SNDTIMEO, (char *) & value, sizeof (int));
|
||||
break;
|
||||
|
||||
case ENET_SOCKOPT_NODELAY:
|
||||
result = setsockopt (socket, IPPROTO_TCP, TCP_NODELAY, (char *) & value, sizeof (int));
|
||||
break;
|
||||
|
||||
case ENET_SOCKOPT_TTL:
|
||||
result = setsockopt (socket, IPPROTO_IP, IP_TTL, (char *) & value, sizeof (int));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result == SOCKET_ERROR ? -1 : 0;
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_get_option (ENetSocket socket, ENetSocketOption option, int * value)
|
||||
{
|
||||
int result = SOCKET_ERROR, len;
|
||||
switch (option)
|
||||
{
|
||||
case ENET_SOCKOPT_ERROR:
|
||||
len = sizeof(int);
|
||||
result = getsockopt (socket, SOL_SOCKET, SO_ERROR, (char *) value, & len);
|
||||
break;
|
||||
|
||||
case ENET_SOCKOPT_TTL:
|
||||
len = sizeof(int);
|
||||
result = getsockopt (socket, IPPROTO_IP, IP_TTL, (char *) value, & len);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result == SOCKET_ERROR ? -1 : 0;
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_connect (ENetSocket socket, const ENetAddress * address)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
int result;
|
||||
|
||||
memset (& sin, 0, sizeof (struct sockaddr_in));
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
|
||||
sin.sin_addr.s_addr = address -> host;
|
||||
|
||||
result = connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
|
||||
if (result == SOCKET_ERROR && WSAGetLastError () != WSAEWOULDBLOCK)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ENetSocket
|
||||
enet_socket_accept (ENetSocket socket, ENetAddress * address)
|
||||
{
|
||||
SOCKET result;
|
||||
struct sockaddr_in sin;
|
||||
int sinLength = sizeof (struct sockaddr_in);
|
||||
|
||||
result = accept (socket,
|
||||
address != NULL ? (struct sockaddr *) & sin : NULL,
|
||||
address != NULL ? & sinLength : NULL);
|
||||
|
||||
if (result == INVALID_SOCKET)
|
||||
return ENET_SOCKET_NULL;
|
||||
|
||||
if (address != NULL)
|
||||
{
|
||||
address -> host = (enet_uint32) sin.sin_addr.s_addr;
|
||||
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_shutdown (ENetSocket socket, ENetSocketShutdown how)
|
||||
{
|
||||
return shutdown (socket, (int) how) == SOCKET_ERROR ? -1 : 0;
|
||||
}
|
||||
|
||||
void
|
||||
enet_socket_destroy (ENetSocket socket)
|
||||
{
|
||||
if (socket != INVALID_SOCKET)
|
||||
closesocket (socket);
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_send (ENetSocket socket,
|
||||
const ENetAddress * address,
|
||||
const ENetBuffer * buffers,
|
||||
size_t bufferCount)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
DWORD sentLength = 0;
|
||||
|
||||
if (address != NULL)
|
||||
{
|
||||
memset (& sin, 0, sizeof (struct sockaddr_in));
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
|
||||
sin.sin_addr.s_addr = address -> host;
|
||||
}
|
||||
|
||||
if (WSASendTo (socket,
|
||||
(LPWSABUF) buffers,
|
||||
(DWORD) bufferCount,
|
||||
& sentLength,
|
||||
0,
|
||||
address != NULL ? (struct sockaddr *) & sin : NULL,
|
||||
address != NULL ? sizeof (struct sockaddr_in) : 0,
|
||||
NULL,
|
||||
NULL) == SOCKET_ERROR)
|
||||
{
|
||||
if (WSAGetLastError () == WSAEWOULDBLOCK)
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (int) sentLength;
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_receive (ENetSocket socket,
|
||||
ENetAddress * address,
|
||||
ENetBuffer * buffers,
|
||||
size_t bufferCount)
|
||||
{
|
||||
INT sinLength = sizeof (struct sockaddr_in);
|
||||
DWORD flags = 0,
|
||||
recvLength = 0;
|
||||
struct sockaddr_in sin;
|
||||
|
||||
if (WSARecvFrom (socket,
|
||||
(LPWSABUF) buffers,
|
||||
(DWORD) bufferCount,
|
||||
& recvLength,
|
||||
& flags,
|
||||
address != NULL ? (struct sockaddr *) & sin : NULL,
|
||||
address != NULL ? & sinLength : NULL,
|
||||
NULL,
|
||||
NULL) == SOCKET_ERROR)
|
||||
{
|
||||
switch (WSAGetLastError ())
|
||||
{
|
||||
case WSAEWOULDBLOCK:
|
||||
case WSAECONNRESET:
|
||||
return 0;
|
||||
case WSAEINTR:
|
||||
case WSAEMSGSIZE:
|
||||
return -2;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & MSG_PARTIAL)
|
||||
return -2;
|
||||
|
||||
if (address != NULL)
|
||||
{
|
||||
address -> host = (enet_uint32) sin.sin_addr.s_addr;
|
||||
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
|
||||
}
|
||||
|
||||
return (int) recvLength;
|
||||
}
|
||||
|
||||
int
|
||||
enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout)
|
||||
{
|
||||
struct timeval timeVal;
|
||||
|
||||
timeVal.tv_sec = timeout / 1000;
|
||||
timeVal.tv_usec = (timeout % 1000) * 1000;
|
||||
|
||||
return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal);
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
|
||||
{
|
||||
fd_set readSet, writeSet;
|
||||
struct timeval timeVal;
|
||||
int selectCount;
|
||||
|
||||
timeVal.tv_sec = timeout / 1000;
|
||||
timeVal.tv_usec = (timeout % 1000) * 1000;
|
||||
|
||||
FD_ZERO (& readSet);
|
||||
FD_ZERO (& writeSet);
|
||||
|
||||
if (* condition & ENET_SOCKET_WAIT_SEND)
|
||||
FD_SET (socket, & writeSet);
|
||||
|
||||
if (* condition & ENET_SOCKET_WAIT_RECEIVE)
|
||||
FD_SET (socket, & readSet);
|
||||
|
||||
selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
|
||||
|
||||
if (selectCount < 0)
|
||||
return -1;
|
||||
|
||||
* condition = ENET_SOCKET_WAIT_NONE;
|
||||
|
||||
if (selectCount == 0)
|
||||
return 0;
|
||||
|
||||
if (FD_ISSET (socket, & writeSet))
|
||||
* condition |= ENET_SOCKET_WAIT_SEND;
|
||||
|
||||
if (FD_ISSET (socket, & readSet))
|
||||
* condition |= ENET_SOCKET_WAIT_RECEIVE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,516 @@
|
||||
/** \file
|
||||
* \brief User API
|
||||
* IUP - A Portable User Interface Toolkit
|
||||
* Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil
|
||||
* http://www.tecgraf.puc-rio.br/iup mailto:iup@tecgraf.puc-rio.br
|
||||
*
|
||||
* See Copyright Notice at the end of this file
|
||||
*/
|
||||
|
||||
#ifndef __IUP_H
|
||||
#define __IUP_H
|
||||
|
||||
#include "iupkey.h"
|
||||
#include "iupdef.h"
|
||||
#include "iup_export.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define IUP_NAME "IUP - Portable User Interface"
|
||||
#define IUP_DESCRIPTION "Multi-platform Toolkit for Building Graphical User Interfaces"
|
||||
#define IUP_COPYRIGHT "Copyright (C) 1994-2023 Tecgraf/PUC-Rio"
|
||||
#define IUP_VERSION "3.31" /* bug fixes are reported only by IupVersion functions */
|
||||
#define IUP_VERSION_NUMBER 331000
|
||||
#define IUP_VERSION_DATE "2023/10/13" /* does not include bug fix releases */
|
||||
|
||||
typedef struct Ihandle_ Ihandle;
|
||||
typedef int (*Icallback)(Ihandle*);
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Main API */
|
||||
/************************************************************************/
|
||||
|
||||
IUP_API int IupOpen (int *argc, char ***argv);
|
||||
IUP_API void IupClose (void);
|
||||
IUP_API int IupIsOpened (void);
|
||||
|
||||
IUPIMGLIB_API void IupImageLibOpen(void);
|
||||
|
||||
IUP_API int IupMainLoop (void);
|
||||
IUP_API int IupLoopStep (void);
|
||||
IUP_API int IupLoopStepWait (void);
|
||||
IUP_API int IupMainLoopLevel (void);
|
||||
IUP_API void IupFlush (void);
|
||||
IUP_API void IupExitLoop (void);
|
||||
IUP_API void IupPostMessage (Ihandle* ih, const char* s, int i, double d, void* p);
|
||||
|
||||
IUP_API int IupRecordInput(const char* filename, int mode);
|
||||
IUP_API int IupPlayInput(const char* filename);
|
||||
|
||||
IUP_API void IupUpdate (Ihandle* ih);
|
||||
IUP_API void IupUpdateChildren(Ihandle* ih);
|
||||
IUP_API void IupRedraw (Ihandle* ih, int children);
|
||||
IUP_API void IupRefresh (Ihandle* ih);
|
||||
IUP_API void IupRefreshChildren(Ihandle* ih);
|
||||
|
||||
IUP_API int IupExecute(const char *filename, const char* parameters);
|
||||
IUP_API int IupExecuteWait(const char *filename, const char* parameters);
|
||||
IUP_API int IupHelp(const char* url);
|
||||
IUP_API void IupLog(const char* type, const char* format, ...);
|
||||
|
||||
IUP_API char* IupLoad (const char *filename);
|
||||
IUP_API char* IupLoadBuffer (const char *buffer);
|
||||
|
||||
IUP_API char* IupVersion (void);
|
||||
IUP_API char* IupVersionDate (void);
|
||||
IUP_API int IupVersionNumber (void);
|
||||
IUP_API void IupVersionShow (void);
|
||||
|
||||
IUP_API void IupSetLanguage (const char *lng);
|
||||
IUP_API char* IupGetLanguage (void);
|
||||
IUP_API void IupSetLanguageString(const char* name, const char* str);
|
||||
IUP_API void IupStoreLanguageString(const char* name, const char* str);
|
||||
IUP_API char* IupGetLanguageString(const char* name);
|
||||
IUP_API void IupSetLanguagePack(Ihandle* ih);
|
||||
|
||||
IUP_API void IupDestroy (Ihandle* ih);
|
||||
IUP_API void IupDetach (Ihandle* child);
|
||||
IUP_API Ihandle* IupAppend (Ihandle* ih, Ihandle* child);
|
||||
IUP_API Ihandle* IupInsert (Ihandle* ih, Ihandle* ref_child, Ihandle* child);
|
||||
IUP_API Ihandle* IupGetChild (Ihandle* ih, int pos);
|
||||
IUP_API int IupGetChildPos (Ihandle* ih, Ihandle* child);
|
||||
IUP_API int IupGetChildCount(Ihandle* ih);
|
||||
IUP_API Ihandle* IupGetNextChild (Ihandle* ih, Ihandle* child);
|
||||
IUP_API Ihandle* IupGetBrother (Ihandle* ih);
|
||||
IUP_API Ihandle* IupGetParent (Ihandle* ih);
|
||||
IUP_API Ihandle* IupGetDialog (Ihandle* ih);
|
||||
IUP_API Ihandle* IupGetDialogChild(Ihandle* ih, const char* name);
|
||||
IUP_API int IupReparent (Ihandle* ih, Ihandle* new_parent, Ihandle* ref_child);
|
||||
|
||||
IUP_API int IupPopup (Ihandle* ih, int x, int y);
|
||||
IUP_API int IupShow (Ihandle* ih);
|
||||
IUP_API int IupShowXY (Ihandle* ih, int x, int y);
|
||||
IUP_API int IupHide (Ihandle* ih);
|
||||
IUP_API int IupMap (Ihandle* ih);
|
||||
IUP_API void IupUnmap (Ihandle* ih);
|
||||
|
||||
IUP_API void IupResetAttribute(Ihandle* ih, const char* name);
|
||||
IUP_API int IupGetAllAttributes(Ihandle* ih, char** names, int n);
|
||||
IUP_API void IupCopyAttributes(Ihandle* src_ih, Ihandle* dst_ih);
|
||||
IUP_API Ihandle* IupSetAtt(const char* handle_name, Ihandle* ih, const char* name, ...);
|
||||
IUP_API Ihandle* IupSetAttributes (Ihandle* ih, const char *str);
|
||||
IUP_API char* IupGetAttributes (Ihandle* ih);
|
||||
|
||||
IUP_API void IupSetAttribute (Ihandle* ih, const char* name, const char* value);
|
||||
IUP_API void IupSetStrAttribute(Ihandle* ih, const char* name, const char* value);
|
||||
IUP_API void IupSetStrf (Ihandle* ih, const char* name, const char* format, ...);
|
||||
IUP_API void IupSetInt (Ihandle* ih, const char* name, int value);
|
||||
IUP_API void IupSetFloat (Ihandle* ih, const char* name, float value);
|
||||
IUP_API void IupSetDouble (Ihandle* ih, const char* name, double value);
|
||||
IUP_API void IupSetRGB (Ihandle* ih, const char* name, unsigned char r, unsigned char g, unsigned char b);
|
||||
IUP_API void IupSetRGBA (Ihandle* ih, const char* name, unsigned char r, unsigned char g, unsigned char b, unsigned char a);
|
||||
|
||||
IUP_API char* IupGetAttribute(Ihandle* ih, const char* name);
|
||||
IUP_API int IupGetInt (Ihandle* ih, const char* name);
|
||||
IUP_API int IupGetInt2 (Ihandle* ih, const char* name);
|
||||
IUP_API int IupGetIntInt (Ihandle* ih, const char* name, int *i1, int *i2);
|
||||
IUP_API float IupGetFloat (Ihandle* ih, const char* name);
|
||||
IUP_API double IupGetDouble(Ihandle* ih, const char* name);
|
||||
IUP_API void IupGetRGB (Ihandle* ih, const char* name, unsigned char *r, unsigned char *g, unsigned char *b);
|
||||
IUP_API void IupGetRGBA (Ihandle* ih, const char* name, unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a);
|
||||
|
||||
IUP_API void IupSetAttributeId(Ihandle* ih, const char* name, int id, const char *value);
|
||||
IUP_API void IupSetStrAttributeId(Ihandle* ih, const char* name, int id, const char *value);
|
||||
IUP_API void IupSetStrfId(Ihandle* ih, const char* name, int id, const char* format, ...);
|
||||
IUP_API void IupSetIntId(Ihandle* ih, const char* name, int id, int value);
|
||||
IUP_API void IupSetFloatId(Ihandle* ih, const char* name, int id, float value);
|
||||
IUP_API void IupSetDoubleId(Ihandle* ih, const char* name, int id, double value);
|
||||
IUP_API void IupSetRGBId(Ihandle* ih, const char* name, int id, unsigned char r, unsigned char g, unsigned char b);
|
||||
|
||||
IUP_API char* IupGetAttributeId(Ihandle* ih, const char* name, int id);
|
||||
IUP_API int IupGetIntId(Ihandle* ih, const char* name, int id);
|
||||
IUP_API float IupGetFloatId(Ihandle* ih, const char* name, int id);
|
||||
IUP_API double IupGetDoubleId(Ihandle* ih, const char* name, int id);
|
||||
IUP_API void IupGetRGBId(Ihandle* ih, const char* name, int id, unsigned char *r, unsigned char *g, unsigned char *b);
|
||||
|
||||
IUP_API void IupSetAttributeId2(Ihandle* ih, const char* name, int lin, int col, const char* value);
|
||||
IUP_API void IupSetStrAttributeId2(Ihandle* ih, const char* name, int lin, int col, const char* value);
|
||||
IUP_API void IupSetStrfId2(Ihandle* ih, const char* name, int lin, int col, const char* format, ...);
|
||||
IUP_API void IupSetIntId2(Ihandle* ih, const char* name, int lin, int col, int value);
|
||||
IUP_API void IupSetFloatId2(Ihandle* ih, const char* name, int lin, int col, float value);
|
||||
IUP_API void IupSetDoubleId2(Ihandle* ih, const char* name, int lin, int col, double value);
|
||||
IUP_API void IupSetRGBId2(Ihandle* ih, const char* name, int lin, int col, unsigned char r, unsigned char g, unsigned char b);
|
||||
|
||||
IUP_API char* IupGetAttributeId2(Ihandle* ih, const char* name, int lin, int col);
|
||||
IUP_API int IupGetIntId2(Ihandle* ih, const char* name, int lin, int col);
|
||||
IUP_API float IupGetFloatId2(Ihandle* ih, const char* name, int lin, int col);
|
||||
IUP_API double IupGetDoubleId2(Ihandle* ih, const char* name, int lin, int col);
|
||||
IUP_API void IupGetRGBId2(Ihandle* ih, const char* name, int lin, int col, unsigned char *r, unsigned char *g, unsigned char *b);
|
||||
|
||||
IUP_API void IupSetGlobal (const char* name, const char* value);
|
||||
IUP_API void IupSetStrGlobal(const char* name, const char* value);
|
||||
IUP_API char* IupGetGlobal (const char* name);
|
||||
|
||||
IUP_API Ihandle* IupSetFocus (Ihandle* ih);
|
||||
IUP_API Ihandle* IupGetFocus (void);
|
||||
IUP_API Ihandle* IupPreviousField(Ihandle* ih);
|
||||
IUP_API Ihandle* IupNextField (Ihandle* ih);
|
||||
|
||||
IUP_API Icallback IupGetCallback (Ihandle* ih, const char *name);
|
||||
IUP_API Icallback IupSetCallback (Ihandle* ih, const char *name, Icallback func);
|
||||
IUP_API Ihandle* IupSetCallbacks(Ihandle* ih, const char *name, Icallback func, ...);
|
||||
|
||||
IUP_API Icallback IupGetFunction(const char *name);
|
||||
IUP_API Icallback IupSetFunction(const char *name, Icallback func);
|
||||
|
||||
IUP_API Ihandle* IupGetHandle (const char *name);
|
||||
IUP_API Ihandle* IupSetHandle (const char *name, Ihandle* ih);
|
||||
IUP_API int IupGetAllNames (char** names, int n);
|
||||
IUP_API int IupGetAllDialogs(char** names, int n);
|
||||
IUP_API char* IupGetName (Ihandle* ih);
|
||||
|
||||
IUP_API void IupSetAttributeHandle(Ihandle* ih, const char* name, Ihandle* ih_named);
|
||||
IUP_API Ihandle* IupGetAttributeHandle(Ihandle* ih, const char* name);
|
||||
IUP_API void IupSetAttributeHandleId(Ihandle* ih, const char* name, int id, Ihandle* ih_named);
|
||||
IUP_API Ihandle* IupGetAttributeHandleId(Ihandle* ih, const char* name, int id);
|
||||
IUP_API void IupSetAttributeHandleId2(Ihandle* ih, const char* name, int lin, int col, Ihandle* ih_named);
|
||||
IUP_API Ihandle* IupGetAttributeHandleId2(Ihandle* ih, const char* name, int lin, int col);
|
||||
|
||||
IUP_API char* IupGetClassName(Ihandle* ih);
|
||||
IUP_API char* IupGetClassType(Ihandle* ih);
|
||||
IUP_API int IupGetAllClasses(char** names, int n);
|
||||
IUP_API int IupGetClassAttributes(const char* classname, char** names, int n);
|
||||
IUP_API int IupGetClassCallbacks(const char* classname, char** names, int n);
|
||||
IUP_API void IupSaveClassAttributes(Ihandle* ih);
|
||||
IUP_API void IupCopyClassAttributes(Ihandle* src_ih, Ihandle* dst_ih);
|
||||
IUP_API void IupSetClassDefaultAttribute(const char* classname, const char *name, const char* value);
|
||||
IUP_API int IupClassMatch(Ihandle* ih, const char* classname);
|
||||
|
||||
IUP_API Ihandle* IupCreate (const char *classname);
|
||||
IUP_API Ihandle* IupCreatev(const char *classname, void* *params);
|
||||
IUP_API Ihandle* IupCreatep(const char *classname, void* first, ...);
|
||||
|
||||
/************************************************************************/
|
||||
/* Elements */
|
||||
/************************************************************************/
|
||||
|
||||
IUP_API Ihandle* IupFill (void);
|
||||
IUP_API Ihandle* IupSpace(void);
|
||||
|
||||
IUP_API Ihandle* IupRadio (Ihandle* child);
|
||||
IUP_API Ihandle* IupVbox (Ihandle* child, ...);
|
||||
IUP_API Ihandle* IupVboxv (Ihandle* *children);
|
||||
IUP_API Ihandle* IupZbox (Ihandle* child, ...);
|
||||
IUP_API Ihandle* IupZboxv (Ihandle* *children);
|
||||
IUP_API Ihandle* IupHbox (Ihandle* child, ...);
|
||||
IUP_API Ihandle* IupHboxv (Ihandle* *children);
|
||||
|
||||
IUP_API Ihandle* IupNormalizer (Ihandle* ih_first, ...);
|
||||
IUP_API Ihandle* IupNormalizerv(Ihandle* *ih_list);
|
||||
|
||||
IUP_API Ihandle* IupCbox (Ihandle* child, ...);
|
||||
IUP_API Ihandle* IupCboxv (Ihandle* *children);
|
||||
IUP_API Ihandle* IupSbox (Ihandle* child);
|
||||
IUP_API Ihandle* IupSplit (Ihandle* child1, Ihandle* child2);
|
||||
IUP_API Ihandle* IupScrollBox (Ihandle* child);
|
||||
IUP_API Ihandle* IupFlatScrollBox(Ihandle* child);
|
||||
IUP_API Ihandle* IupGridBox (Ihandle* child, ...);
|
||||
IUP_API Ihandle* IupGridBoxv (Ihandle* *children);
|
||||
IUP_API Ihandle* IupMultiBox (Ihandle* child, ...);
|
||||
IUP_API Ihandle* IupMultiBoxv (Ihandle **children);
|
||||
IUP_API Ihandle* IupExpander(Ihandle* child);
|
||||
IUP_API Ihandle* IupDetachBox (Ihandle* child);
|
||||
IUP_API Ihandle* IupBackgroundBox(Ihandle* child);
|
||||
|
||||
IUP_API Ihandle* IupFrame (Ihandle* child);
|
||||
IUP_API Ihandle* IupFlatFrame (Ihandle* child);
|
||||
|
||||
IUP_API Ihandle* IupImage (int width, int height, const unsigned char* pixels);
|
||||
IUP_API Ihandle* IupImageRGB (int width, int height, const unsigned char* pixels);
|
||||
IUP_API Ihandle* IupImageRGBA (int width, int height, const unsigned char* pixels);
|
||||
|
||||
IUP_API Ihandle* IupItem (const char* title, const char* action);
|
||||
IUP_API Ihandle* IupSubmenu (const char* title, Ihandle* child);
|
||||
IUP_API Ihandle* IupSeparator (void);
|
||||
IUP_API Ihandle* IupMenu (Ihandle* child, ...);
|
||||
IUP_API Ihandle* IupMenuv (Ihandle* *children);
|
||||
|
||||
IUP_API Ihandle* IupButton (const char* title, const char* action);
|
||||
IUP_API Ihandle* IupFlatButton (const char* title);
|
||||
IUP_API Ihandle* IupFlatToggle (const char* title);
|
||||
IUP_API Ihandle* IupDropButton (Ihandle* dropchild);
|
||||
IUP_API Ihandle* IupFlatLabel (const char* title);
|
||||
IUP_API Ihandle* IupFlatSeparator(void);
|
||||
IUP_API Ihandle* IupCanvas (const char* action);
|
||||
IUP_API Ihandle* IupDialog (Ihandle* child);
|
||||
IUP_API Ihandle* IupUser (void);
|
||||
IUP_API Ihandle* IupThread (void);
|
||||
IUP_API Ihandle* IupLabel (const char* title);
|
||||
IUP_API Ihandle* IupList (const char* action);
|
||||
IUP_API Ihandle* IupFlatList (void);
|
||||
IUP_API Ihandle* IupText (const char* action);
|
||||
IUP_API Ihandle* IupMultiLine (const char* action);
|
||||
IUP_API Ihandle* IupToggle (const char* title, const char* action);
|
||||
IUP_API Ihandle* IupTimer (void);
|
||||
IUP_API Ihandle* IupClipboard (void);
|
||||
IUP_API Ihandle* IupProgressBar(void);
|
||||
IUP_API Ihandle* IupVal (const char *type);
|
||||
IUP_API Ihandle* IupFlatVal (const char *type);
|
||||
IUP_API Ihandle* IupFlatTree (void);
|
||||
IUP_API Ihandle* IupTabs (Ihandle* child, ...);
|
||||
IUP_API Ihandle* IupTabsv (Ihandle* *children);
|
||||
IUP_API Ihandle* IupFlatTabs (Ihandle* first, ...);
|
||||
IUP_API Ihandle* IupFlatTabsv (Ihandle* *children);
|
||||
IUP_API Ihandle* IupTree (void);
|
||||
IUP_API Ihandle* IupLink (const char* url, const char* title);
|
||||
IUP_API Ihandle* IupAnimatedLabel(Ihandle* animation);
|
||||
IUP_API Ihandle* IupDatePick (void);
|
||||
IUP_API Ihandle* IupCalendar (void);
|
||||
IUP_API Ihandle* IupColorbar (void);
|
||||
IUP_API Ihandle* IupGauge (void);
|
||||
IUP_API Ihandle* IupDial (const char* type);
|
||||
IUP_API Ihandle* IupColorBrowser(void);
|
||||
|
||||
/* Old controls, use SPIN attribute of IupText */
|
||||
IUP_API Ihandle* IupSpin (void);
|
||||
IUP_API Ihandle* IupSpinbox (Ihandle* child);
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Utilities */
|
||||
/************************************************************************/
|
||||
|
||||
/* String compare utility */
|
||||
IUP_API int IupStringCompare(const char* str1, const char* str2, int casesensitive, int lexicographic);
|
||||
|
||||
/* IupImage utilities */
|
||||
IUP_API int IupSaveImageAsText(Ihandle* ih, const char* filename, const char* format, const char* name);
|
||||
IUP_API Ihandle* IupImageGetHandle(const char* name);
|
||||
|
||||
/* IupText and IupScintilla utilities */
|
||||
IUP_API void IupTextConvertLinColToPos(Ihandle* ih, int lin, int col, int *pos);
|
||||
IUP_API void IupTextConvertPosToLinCol(Ihandle* ih, int pos, int *lin, int *col);
|
||||
|
||||
/* IupText, IupList, IupTree, IupMatrix and IupScintilla utility */
|
||||
IUP_API int IupConvertXYToPos(Ihandle* ih, int x, int y);
|
||||
|
||||
/* OLD names, kept for backward compatibility, will never be removed. */
|
||||
IUP_API void IupStoreGlobal(const char* name, const char* value);
|
||||
IUP_API void IupStoreAttribute(Ihandle* ih, const char* name, const char* value);
|
||||
IUP_API void IupSetfAttribute(Ihandle* ih, const char* name, const char* format, ...);
|
||||
IUP_API void IupStoreAttributeId(Ihandle* ih, const char* name, int id, const char *value);
|
||||
IUP_API void IupSetfAttributeId(Ihandle* ih, const char* name, int id, const char* f, ...);
|
||||
IUP_API void IupStoreAttributeId2(Ihandle* ih, const char* name, int lin, int col, const char* value);
|
||||
IUP_API void IupSetfAttributeId2(Ihandle* ih, const char* name, int lin, int col, const char* format, ...);
|
||||
|
||||
/* IupTree and IupFlatTree utilities (work for both) */
|
||||
IUP_API int IupTreeSetUserId(Ihandle* ih, int id, void* userid);
|
||||
IUP_API void* IupTreeGetUserId(Ihandle* ih, int id);
|
||||
IUP_API int IupTreeGetId(Ihandle* ih, void *userid);
|
||||
IUP_API void IupTreeSetAttributeHandle(Ihandle* ih, const char* name, int id, Ihandle* ih_named); /* deprecated, use IupSetAttributeHandleId */
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Pre-defined dialogs */
|
||||
/************************************************************************/
|
||||
|
||||
IUP_API Ihandle* IupFileDlg(void);
|
||||
IUP_API Ihandle* IupMessageDlg(void);
|
||||
IUP_API Ihandle* IupColorDlg(void);
|
||||
IUP_API Ihandle* IupFontDlg(void);
|
||||
IUP_API Ihandle* IupProgressDlg(void);
|
||||
|
||||
IUP_API int IupGetFile(char *arq);
|
||||
IUP_API void IupMessage(const char *title, const char *msg);
|
||||
IUP_API void IupMessagef(const char *title, const char *format, ...);
|
||||
IUP_API void IupMessageError(Ihandle* parent, const char* message);
|
||||
IUP_API int IupMessageAlarm(Ihandle* parent, const char* title, const char *message, const char *buttons);
|
||||
IUP_API int IupAlarm(const char *title, const char *msg, const char *b1, const char *b2, const char *b3);
|
||||
IUP_API int IupScanf(const char *format, ...);
|
||||
IUP_API int IupListDialog(int type, const char *title, int size, const char** list,
|
||||
int op, int max_col, int max_lin, int* marks);
|
||||
IUP_API int IupGetText(const char* title, char* text, int maxsize);
|
||||
IUP_API int IupGetColor(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b);
|
||||
|
||||
typedef int (*Iparamcb)(Ihandle* dialog, int param_index, void* user_data);
|
||||
IUP_API int IupGetParam(const char* title, Iparamcb action, void* user_data, const char* format,...);
|
||||
IUP_API int IupGetParamv(const char* title, Iparamcb action, void* user_data, const char* format, int param_count, int param_extra, void** param_data);
|
||||
IUP_API Ihandle* IupParam(const char* format);
|
||||
IUP_API Ihandle* IupParamBox(Ihandle* param, ...);
|
||||
IUP_API Ihandle* IupParamBoxv(Ihandle* *param_array);
|
||||
|
||||
IUP_API Ihandle* IupLayoutDialog(Ihandle* dialog);
|
||||
IUP_API Ihandle* IupElementPropertiesDialog(Ihandle* parent, Ihandle* elem);
|
||||
IUP_API Ihandle* IupGlobalsDialog(void);
|
||||
IUP_API Ihandle* IupClassInfoDialog(Ihandle* parent);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************/
|
||||
/* Common Flags and Return Values */
|
||||
/************************************************************************/
|
||||
#define IUP_ERROR 1
|
||||
#define IUP_NOERROR 0
|
||||
#define IUP_OPENED -1
|
||||
#define IUP_INVALID -1
|
||||
#define IUP_INVALID_ID -10
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Callback Return Values */
|
||||
/************************************************************************/
|
||||
#define IUP_IGNORE -1
|
||||
#define IUP_DEFAULT -2
|
||||
#define IUP_CLOSE -3
|
||||
#define IUP_CONTINUE -4
|
||||
|
||||
/************************************************************************/
|
||||
/* IupPopup and IupShowXY Parameter Values */
|
||||
/************************************************************************/
|
||||
#define IUP_CENTER 0xFFFF /* 65535 */
|
||||
#define IUP_LEFT 0xFFFE /* 65534 */
|
||||
#define IUP_RIGHT 0xFFFD /* 65533 */
|
||||
#define IUP_MOUSEPOS 0xFFFC /* 65532 */
|
||||
#define IUP_CURRENT 0xFFFB /* 65531 */
|
||||
#define IUP_CENTERPARENT 0xFFFA /* 65530 */
|
||||
#define IUP_LEFTPARENT 0xFFF9 /* 65529 */
|
||||
#define IUP_RIGHTPARENT 0xFFF8 /* 65528 */
|
||||
#define IUP_TOP IUP_LEFT
|
||||
#define IUP_BOTTOM IUP_RIGHT
|
||||
#define IUP_TOPPARENT IUP_LEFTPARENT
|
||||
#define IUP_BOTTOMPARENT IUP_RIGHTPARENT
|
||||
|
||||
/************************************************************************/
|
||||
/* SHOW_CB Callback Values */
|
||||
/************************************************************************/
|
||||
enum{IUP_SHOW, IUP_RESTORE, IUP_MINIMIZE, IUP_MAXIMIZE, IUP_HIDE};
|
||||
|
||||
/************************************************************************/
|
||||
/* SCROLL_CB Callback Values */
|
||||
/************************************************************************/
|
||||
enum{IUP_SBUP, IUP_SBDN, IUP_SBPGUP, IUP_SBPGDN, IUP_SBPOSV, IUP_SBDRAGV,
|
||||
IUP_SBLEFT, IUP_SBRIGHT, IUP_SBPGLEFT, IUP_SBPGRIGHT, IUP_SBPOSH, IUP_SBDRAGH};
|
||||
|
||||
/************************************************************************/
|
||||
/* Mouse Button Values and Macros */
|
||||
/************************************************************************/
|
||||
#define IUP_BUTTON1 '1'
|
||||
#define IUP_BUTTON2 '2'
|
||||
#define IUP_BUTTON3 '3'
|
||||
#define IUP_BUTTON4 '4'
|
||||
#define IUP_BUTTON5 '5'
|
||||
|
||||
#define iup_isshift(_s) (_s[0]=='S')
|
||||
#define iup_iscontrol(_s) (_s[1]=='C')
|
||||
#define iup_isbutton1(_s) (_s[2]=='1')
|
||||
#define iup_isbutton2(_s) (_s[3]=='2')
|
||||
#define iup_isbutton3(_s) (_s[4]=='3')
|
||||
#define iup_isdouble(_s) (_s[5]=='D')
|
||||
#define iup_isalt(_s) (_s[6]=='A')
|
||||
#define iup_issys(_s) (_s[7]=='Y')
|
||||
#define iup_isbutton4(_s) (_s[8]=='4')
|
||||
#define iup_isbutton5(_s) (_s[9]=='5')
|
||||
|
||||
/* Old definitions for backward compatibility */
|
||||
#define isshift iup_isshift
|
||||
#define iscontrol iup_iscontrol
|
||||
#define isbutton1 iup_isbutton1
|
||||
#define isbutton2 iup_isbutton2
|
||||
#define isbutton3 iup_isbutton3
|
||||
#define isdouble iup_isdouble
|
||||
#define isalt iup_isalt
|
||||
#define issys iup_issys
|
||||
#define isbutton4 iup_isbutton4
|
||||
#define isbutton5 iup_isbutton5
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Pre-Defined Masks */
|
||||
/************************************************************************/
|
||||
#define IUP_MASK_FLOAT "[+/-]?(/d+/.?/d*|/./d+)"
|
||||
#define IUP_MASK_UFLOAT "(/d+/.?/d*|/./d+)"
|
||||
#define IUP_MASK_EFLOAT "[+/-]?(/d+/.?/d*|/./d+)([eE][+/-]?/d+)?"
|
||||
#define IUP_MASK_UEFLOAT "(/d+/.?/d*|/./d+)([eE][+/-]?/d+)?"
|
||||
#define IUP_MASK_FLOATCOMMA "[+/-]?(/d+/,?/d*|/,/d+)"
|
||||
#define IUP_MASK_UFLOATCOMMA "(/d+/,?/d*|/,/d+)"
|
||||
#define IUP_MASK_INT "[+/-]?/d+"
|
||||
#define IUP_MASK_UINT "/d+"
|
||||
|
||||
/* Old definitions for backward compatibility */
|
||||
#define IUPMASK_FLOAT IUP_MASK_FLOAT
|
||||
#define IUPMASK_UFLOAT IUP_MASK_UFLOAT
|
||||
#define IUPMASK_EFLOAT IUP_MASK_EFLOAT
|
||||
#define IUPMASK_INT IUP_MASK_INT
|
||||
#define IUPMASK_UINT IUP_MASK_UINT
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* IupGetParam Callback situations */
|
||||
/************************************************************************/
|
||||
#define IUP_GETPARAM_BUTTON1 -1
|
||||
#define IUP_GETPARAM_INIT -2
|
||||
#define IUP_GETPARAM_BUTTON2 -3
|
||||
#define IUP_GETPARAM_BUTTON3 -4
|
||||
#define IUP_GETPARAM_CLOSE -5
|
||||
#define IUP_GETPARAM_MAP -6
|
||||
#define IUP_GETPARAM_OK IUP_GETPARAM_BUTTON1
|
||||
#define IUP_GETPARAM_CANCEL IUP_GETPARAM_BUTTON2
|
||||
#define IUP_GETPARAM_HELP IUP_GETPARAM_BUTTON3
|
||||
|
||||
/************************************************************************/
|
||||
/* Used by IupColorbar */
|
||||
/************************************************************************/
|
||||
#define IUP_PRIMARY -1
|
||||
#define IUP_SECONDARY -2
|
||||
|
||||
/************************************************************************/
|
||||
/* Record Input Modes */
|
||||
/************************************************************************/
|
||||
enum {IUP_RECBINARY, IUP_RECTEXT};
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Replacement for the WinMain in Windows, */
|
||||
/* this allows the application to start from "main". */
|
||||
/* Used only for Watcom. */
|
||||
/************************************************************************/
|
||||
#if defined (__WATCOMC__)
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
int IupMain (int argc, char** argv); /* In C++ we have to declare the prototype */
|
||||
}
|
||||
#endif
|
||||
#define main IupMain /* this is the trick for Watcom and MetroWerks */
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* Copyright (C) 1994-2019 Tecgraf/PUC-Rio.
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,464 @@
|
||||
/** \file
|
||||
* \brief Class Callback Utilities.
|
||||
*/
|
||||
|
||||
#ifndef __IUP_CLASS_CBS_HPP
|
||||
#define __IUP_CLASS_CBS_HPP
|
||||
|
||||
|
||||
#define IUP_CLASS_GET_OBJECT(__ih, __class) dynamic_cast<__class*>((__class*)IupGetAttribute(__ih, #__class "->this"))
|
||||
|
||||
|
||||
#define IUP_CLASS_INITCALLBACK(__ih, __class) \
|
||||
IupSetAttribute(__ih, #__class "->this", (char*)this)
|
||||
|
||||
#define IUP_CLASS_SETCALLBACK(__ih, __name, __cb) \
|
||||
IupSetCallback(__ih, __name, (Icallback)CB_##__cb)
|
||||
|
||||
|
||||
|
||||
#ifdef __IUP_PLUS_H
|
||||
|
||||
#define IUP_PLUS_GET_OBJECT(__elem, __class) dynamic_cast<__class*>((__class*)IupGetAttribute(__elem.GetHandle(), #__class "->this"))
|
||||
|
||||
#define IUP_PLUS_INITCALLBACK(__elem, __class) \
|
||||
IupSetAttribute(__elem.GetHandle(), #__class "->this", (char*)this)
|
||||
|
||||
#define IUP_PLUS_SETCALLBACK(__elem, __name, __cb) \
|
||||
IupSetCallback(__elem.GetHandle(), __name, (Icallback)CB_##__cb)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFn(__class, __cb) \
|
||||
int __cb(Ihandle* ih); \
|
||||
static int CB_##__cb(Ihandle* ih) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFni(__class, __cb) \
|
||||
int __cb(Ihandle* ih, int i1); \
|
||||
static int CB_##__cb(Ihandle* ih, int i1) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, i1); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFnii(__class, __cb) \
|
||||
int __cb(Ihandle* ih, int i1, int i2); \
|
||||
static int CB_##__cb(Ihandle* ih, int i1, int i2) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, i1, i2); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFniii(__class, __cb) \
|
||||
int __cb(Ihandle* ih, int i1, int i2, int i3); \
|
||||
static int CB_##__cb(Ihandle* ih, int i1, int i2, int i3) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, i1, i2, i3); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFniiii(__class, __cb) \
|
||||
int __cb(Ihandle* ih, int i1, int i2, int i3, int i4); \
|
||||
static int CB_##__cb(Ihandle* ih, int i1, int i2, int i3, int i4) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, i1, i2, i3, i4); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFniiiii(__class, __cb) \
|
||||
int __cb(Ihandle* ih, int i1, int i2, int i3, int i4, int i5); \
|
||||
static int CB_##__cb(Ihandle* ih, int i1, int i2, int i3, int i4, int i5) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, i1, i2, i3, i4, i5); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFniiiiii(__class, __cb) \
|
||||
int __cb(Ihandle* ih, int i1, int i2, int i3, int i4, int i5, int i6); \
|
||||
static int CB_##__cb(Ihandle* ih, int i1, int i2, int i3, int i4, int i5, int i6) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, i1, i2, i3, i4, i5, i6); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFniiiiiiC(__class, __cb) \
|
||||
int __cb(Ihandle* ih, int i1, int i2, int i3, int i4, int i5, int i6, struct _cdCanvas* canvas); \
|
||||
static int CB_##__cb(Ihandle* ih, int i1, int i2, int i3, int i4, int i5, int i6, struct _cdCanvas* canvas) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, i1, i2, i3, i4, i5, i6, canvas); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFnC(__class, __cb) \
|
||||
int __cb(Ihandle* ih, struct _cdCanvas* canvas); \
|
||||
static int CB_##__cb(Ihandle* ih, struct _cdCanvas* canvas) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, canvas); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_dIFnii(__class, __cb) \
|
||||
double __cb(Ihandle* ih, int i1, int i2); \
|
||||
static double CB_##__cb(Ihandle* ih, int i1, int i2) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, i1, i2); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_sIFni(__class, __cb) \
|
||||
char* __cb(Ihandle* ih, int i1); \
|
||||
static char* CB_##__cb(Ihandle* ih, int i1) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, i1); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_sIFnii(__class, __cb) \
|
||||
char* __cb(Ihandle* ih, int i1, int i2); \
|
||||
static char* CB_##__cb(Ihandle* ih, int i1, int i2) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, i1, i2); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_sIFniis(__class, __cb) \
|
||||
char* __cb(Ihandle* ih, int i1, int i2, char* s); \
|
||||
static char* CB_##__cb(Ihandle* ih, int i1, int i2, char* s) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, i1, i2, s); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFnff(__class, __cb) \
|
||||
int __cb(Ihandle* ih, float f1, float f2); \
|
||||
static int CB_##__cb(Ihandle* ih, float f1, float f2) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, f1, f2); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFniff(__class, __cb) \
|
||||
int __cb(Ihandle* ih, int i1, float f1, float f2); \
|
||||
static int CB_##__cb(Ihandle* ih, int i1, float f1, float f2) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, i1, f1, f2); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFnfiis(__class, __cb) \
|
||||
int __cb(Ihandle* ih, float f1, int i1, int i2, char* s); \
|
||||
static int CB_##__cb(Ihandle* ih, float f1, int i1, int i2, char* s) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, f1, i1, i2, s); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFnd(__class, __cb) \
|
||||
int __cb(Ihandle* ih, double d1); \
|
||||
static int CB_##__cb(Ihandle* ih, double d1) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, d1); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFndds(__class, __cb) \
|
||||
int __cb(Ihandle* ih, double d1, double d2, char* s); \
|
||||
static int CB_##__cb(Ihandle* ih, double d1, double d2, char* s) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, d1, d2, s); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFniid(__class, __cb) \
|
||||
int __cb(Ihandle* ih, int i1, int i2, double d1); \
|
||||
static int CB_##__cb(Ihandle* ih, int i1, int i2, double d1) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, i1, i2, d1); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFniidd(__class, __cb) \
|
||||
int __cb(Ihandle* ih, int i1, int i2, double d1, double d2); \
|
||||
static int CB_##__cb(Ihandle* ih, int i1, int i2, double d1, double d2) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, i1, i2, d1, d2); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFniiddi(__class, __cb) \
|
||||
int __cb(Ihandle* ih, int i1, int i2, double d1, double d2, int i3); \
|
||||
static int CB_##__cb(Ihandle* ih, int i1, int i2, double d1, double d2, int i3) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, i1, i2, d1, d2, i3); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFniidds(__class, __cb) \
|
||||
int __cb(Ihandle* ih, int i1, int i2, double d1, double d2, char* s); \
|
||||
static int CB_##__cb(Ihandle* ih, int i1, int i2, double d1, double d2, char* s) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, i1, i2, d1, d2, s); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFniiIII(__class, __cb) \
|
||||
int __cb(Ihandle* ih, int i1, int i2, int *I1, int *I2, int *I3); \
|
||||
static int CB_##__cb(Ihandle* ih, int i1, int i2, int *I1, int *I2, int *I3) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, i1, i2, I1, I2, I3); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFniIIII(__class, __cb) \
|
||||
int __cb(Ihandle* ih, int i1, int *I1, int *I2, int *I3, int *I4); \
|
||||
static int CB_##__cb(Ihandle* ih, int i1, int *I1, int *I2, int *I3, int *I4) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, i1, I1, I2, I3, I4); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFnIi(__class, __cb) \
|
||||
int __cb(Ihandle* ih, int *I1, int i1); \
|
||||
static int CB_##__cb(Ihandle* ih, int *I1, int i1) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, I1, i1); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFnccc(__class, __cb) \
|
||||
int __cb(Ihandle* ih, char c1, char c2, char c3); \
|
||||
static int CB_##__cb(Ihandle* ih, char c1, char c2, char c3) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, c1, c2, c3); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFnis(__class, __cb) \
|
||||
int __cb(Ihandle* ih, int i1, char* s); \
|
||||
static int CB_##__cb(Ihandle* ih, int i1, char* s) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, i1, s); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFniis(__class, __cb) \
|
||||
int __cb(Ihandle* ih, int i1, int i2, char* s); \
|
||||
static int CB_##__cb(Ihandle* ih, int i1, int i2, char* s) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, i1, i2, s); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFniiis(__class, __cb) \
|
||||
int __cb(Ihandle* ih, int i1, int i2, int i3, char* s); \
|
||||
static int CB_##__cb(Ihandle* ih, int i1, int i2, int i3, char* s) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, i1, i2, i3, s); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFniiiis(__class, __cb) \
|
||||
int __cb(Ihandle* ih, int i1, int i2, int i3, int i4, char* s); \
|
||||
static int CB_##__cb(Ihandle* ih, int i1, int i2, int i3, int i4, char* s) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, i1, i2, i3, i4, s); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFniiiiis(__class, __cb) \
|
||||
int __cb(Ihandle* ih, int i1, int i2, int i3, int i4, int i5, char* s); \
|
||||
static int CB_##__cb(Ihandle* ih, int i1, int i2, int i3, int i4, int i5, char* s) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, i1, i2, i3, i4, i5, s); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFniiiiiis(__class, __cb) \
|
||||
int __cb(Ihandle* ih, int i1, int i2, int i3, int i4, int i5, int i6, char* s); \
|
||||
static int CB_##__cb(Ihandle* ih, int i1, int i2, int i3, int i4, int i5, int i6, char* s) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, i1, i2, i3, i4, i5, i6, s); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFnss(__class, __cb) \
|
||||
int __cb(Ihandle* ih, char* s1, char* s2); \
|
||||
static int CB_##__cb(Ihandle* ih, char* s1, char* s2) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, s1, s2); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFns(__class, __cb) \
|
||||
int __cb(Ihandle* ih, char* s1); \
|
||||
static int CB_##__cb(Ihandle* ih, char* s1) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, s1); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFnsi(__class, __cb) \
|
||||
int __cb(Ihandle* ih, char* s1, int i1); \
|
||||
static int CB_##__cb(Ihandle* ih, char* s1, int i1) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, s1, i1); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFnsii(__class, __cb) \
|
||||
int __cb(Ihandle* ih, char* s1, int i1, int i2); \
|
||||
static int CB_##__cb(Ihandle* ih, char* s1, int i1, int i2) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, s1, i1, i2); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFnsiii(__class, __cb) \
|
||||
int __cb(Ihandle* ih, char* s1, int i1, int i2, int i3); \
|
||||
static int CB_##__cb(Ihandle* ih, char* s1, int i1, int i2, int i3) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, s1, i1, i2, i3); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFnnii(__class, __cb) \
|
||||
int __cb(Ihandle* ih, Ihandle* ih1, int i1, int i2); \
|
||||
static int CB_##__cb(Ihandle* ih, Ihandle* ih1, int i1, int i2) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, ih1, i1, i2); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFnnn(__class, __cb) \
|
||||
int __cb(Ihandle* ih, Ihandle* ih1, Ihandle *ih2); \
|
||||
static int CB_##__cb(Ihandle* ih, Ihandle* ih1, Ihandle *ih2) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, ih1, ih2); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFniinsii(__class, __cb) \
|
||||
int __cb(Ihandle* ih, int i1, int i2, Ihandle* ih1, char* s, int i3, int i4); \
|
||||
static int CB_##__cb(Ihandle* ih, int i1, int i2, Ihandle* ih1, char* s, int i3, int i4) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, i1, i2, ih1, s, i3, i4); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFnsVi(__class, __cb) \
|
||||
int __cb(Ihandle* ih, char* s1, void* V1, int i1); \
|
||||
static int CB_##__cb(Ihandle* ih, char* s1, void* V1, int i1) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, s1, V1, i1); \
|
||||
}
|
||||
|
||||
#define IUP_CLASS_DECLARECALLBACK_IFnsViii(__class, __cb) \
|
||||
int __cb(Ihandle* ih, char* s1, void* V1, int i1, int i2, int i3); \
|
||||
static int CB_##__cb(Ihandle* ih, char* s1, void* V1, int i1, int i2, int i3) \
|
||||
{ \
|
||||
__class* obj = IUP_CLASS_GET_OBJECT(ih, __class); \
|
||||
return obj->__cb(ih, s1, V1, i1, i2, i3); \
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* #define IUP_CLASS_DEBUG */
|
||||
#ifdef IUP_CLASS_DEBUG
|
||||
class IUP_CLASS_DUMMY
|
||||
{
|
||||
// Used to check for errors in the definitions
|
||||
IUP_CLASS_DECLARECALLBACK_IFn(IUP_CLASS_DUMMY, IFn);
|
||||
IUP_CLASS_DECLARECALLBACK_IFni(IUP_CLASS_DUMMY, IFni);
|
||||
IUP_CLASS_DECLARECALLBACK_IFnii(IUP_CLASS_DUMMY, IFnii);
|
||||
IUP_CLASS_DECLARECALLBACK_IFniii(IUP_CLASS_DUMMY, IFniii);
|
||||
IUP_CLASS_DECLARECALLBACK_IFniiii(IUP_CLASS_DUMMY, IFniiii);
|
||||
IUP_CLASS_DECLARECALLBACK_IFniiiii(IUP_CLASS_DUMMY, IFniiiii);
|
||||
IUP_CLASS_DECLARECALLBACK_IFniiiiii(IUP_CLASS_DUMMY, IFniiiiii);
|
||||
IUP_CLASS_DECLARECALLBACK_IFniiiiiiC(IUP_CLASS_DUMMY, IFniiiiiiC);
|
||||
IUP_CLASS_DECLARECALLBACK_IFnC(IUP_CLASS_DUMMY, IFnC);
|
||||
IUP_CLASS_DECLARECALLBACK_dIFnii(IUP_CLASS_DUMMY, dIFnii);
|
||||
IUP_CLASS_DECLARECALLBACK_sIFni(IUP_CLASS_DUMMY, sIFni);
|
||||
IUP_CLASS_DECLARECALLBACK_sIFnii(IUP_CLASS_DUMMY, sIFnii);
|
||||
IUP_CLASS_DECLARECALLBACK_sIFniis(IUP_CLASS_DUMMY, sIFniis);
|
||||
IUP_CLASS_DECLARECALLBACK_IFnff(IUP_CLASS_DUMMY, IFnff);
|
||||
IUP_CLASS_DECLARECALLBACK_IFniff(IUP_CLASS_DUMMY, IFniff);
|
||||
IUP_CLASS_DECLARECALLBACK_IFnfiis(IUP_CLASS_DUMMY, IFnfiis);
|
||||
IUP_CLASS_DECLARECALLBACK_IFnd(IUP_CLASS_DUMMY, IFnd);
|
||||
IUP_CLASS_DECLARECALLBACK_IFndds(IUP_CLASS_DUMMY, IFndds);
|
||||
IUP_CLASS_DECLARECALLBACK_IFniid(IUP_CLASS_DUMMY, IFniid);
|
||||
IUP_CLASS_DECLARECALLBACK_IFniidd(IUP_CLASS_DUMMY, IFniidd);
|
||||
IUP_CLASS_DECLARECALLBACK_IFniiddi(IUP_CLASS_DUMMY, IFniiddi);
|
||||
IUP_CLASS_DECLARECALLBACK_IFniidds(IUP_CLASS_DUMMY, IFniidds);
|
||||
IUP_CLASS_DECLARECALLBACK_IFniiIII(IUP_CLASS_DUMMY, IFniiIII);
|
||||
IUP_CLASS_DECLARECALLBACK_IFniIIII(IUP_CLASS_DUMMY, IFniIIII);
|
||||
IUP_CLASS_DECLARECALLBACK_IFnIi(IUP_CLASS_DUMMY, IFnIi);
|
||||
IUP_CLASS_DECLARECALLBACK_IFnccc(IUP_CLASS_DUMMY, IFnccc);
|
||||
IUP_CLASS_DECLARECALLBACK_IFnis(IUP_CLASS_DUMMY, IFnis);
|
||||
IUP_CLASS_DECLARECALLBACK_IFniis(IUP_CLASS_DUMMY, IFniis);
|
||||
IUP_CLASS_DECLARECALLBACK_IFniiis(IUP_CLASS_DUMMY, IFniiis);
|
||||
IUP_CLASS_DECLARECALLBACK_IFniiiis(IUP_CLASS_DUMMY, IFniiiis);
|
||||
IUP_CLASS_DECLARECALLBACK_IFniiiiis(IUP_CLASS_DUMMY, IFniiiiis);
|
||||
IUP_CLASS_DECLARECALLBACK_IFniiiiiis(IUP_CLASS_DUMMY, IFniiiiiis);
|
||||
IUP_CLASS_DECLARECALLBACK_IFnss(IUP_CLASS_DUMMY, IFnss);
|
||||
IUP_CLASS_DECLARECALLBACK_IFns(IUP_CLASS_DUMMY, IFns);
|
||||
IUP_CLASS_DECLARECALLBACK_IFnsi(IUP_CLASS_DUMMY, IFnsi);
|
||||
IUP_CLASS_DECLARECALLBACK_IFnsii(IUP_CLASS_DUMMY, IFnsii);
|
||||
IUP_CLASS_DECLARECALLBACK_IFnsiii(IUP_CLASS_DUMMY, IFnsiii);
|
||||
IUP_CLASS_DECLARECALLBACK_IFnnii(IUP_CLASS_DUMMY, IFnnii);
|
||||
IUP_CLASS_DECLARECALLBACK_IFnnn(IUP_CLASS_DUMMY, IFnnn);
|
||||
IUP_CLASS_DECLARECALLBACK_IFniinsii(IUP_CLASS_DUMMY, IFniinsii);
|
||||
IUP_CLASS_DECLARECALLBACK_IFnsVi(IUP_CLASS_DUMMY, IFnsVi);
|
||||
IUP_CLASS_DECLARECALLBACK_IFnsViii(IUP_CLASS_DUMMY, IFnsViii);
|
||||
};
|
||||
|
||||
class SampleClass
|
||||
{
|
||||
int sample_count;
|
||||
|
||||
public:
|
||||
SampleClass()
|
||||
{
|
||||
sample_count = 0;
|
||||
|
||||
Ihandle* button1 = IupButton("Inc", NULL);
|
||||
Ihandle* button2 = IupButton("Dec", NULL);
|
||||
Ihandle* dialog = IupDialog(IupHbox(button1, button2, NULL));
|
||||
|
||||
// 1) Register "this" object as a callback receiver (need only once)
|
||||
IUP_CLASS_INITCALLBACK(dialog, SampleClass);
|
||||
|
||||
// 2) Associate the callback with the button
|
||||
IUP_CLASS_SETCALLBACK(button1, "ACTION", ButtonAction1);
|
||||
IUP_CLASS_SETCALLBACK(button2, "ACTION", ButtonAction2);
|
||||
|
||||
IupShow(dialog);
|
||||
};
|
||||
|
||||
protected:
|
||||
// 3) Declare the callback as a member function
|
||||
IUP_CLASS_DECLARECALLBACK_IFn(SampleClass, ButtonAction1);
|
||||
IUP_CLASS_DECLARECALLBACK_IFn(SampleClass, ButtonAction2);
|
||||
};
|
||||
|
||||
// 4) Define the callback as a member function
|
||||
int SampleClass::ButtonAction1(Ihandle*)
|
||||
{
|
||||
sample_count++;
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
int SampleClass::ButtonAction2(Ihandle*)
|
||||
{
|
||||
sample_count--;
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
#endif // IUP_CLASS_DEBUG
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,60 @@
|
||||
/** \file
|
||||
* \brief Configuration file Utilities
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef IUP_CONFIG_H
|
||||
#define IUP_CONFIG_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
IUP_API Ihandle* IupConfig(void);
|
||||
|
||||
IUP_API int IupConfigLoad(Ihandle* ih);
|
||||
IUP_API int IupConfigSave(Ihandle* ih);
|
||||
|
||||
/****************************************************************/
|
||||
|
||||
IUP_API void IupConfigSetVariableStr(Ihandle* ih, const char* group, const char* key, const char* value);
|
||||
IUP_API void IupConfigSetVariableStrId(Ihandle* ih, const char* group, const char* key, int id, const char* value);
|
||||
IUP_API void IupConfigSetVariableInt(Ihandle* ih, const char* group, const char* key, int value);
|
||||
IUP_API void IupConfigSetVariableIntId(Ihandle* ih, const char* group, const char* key, int id, int value);
|
||||
IUP_API void IupConfigSetVariableDouble(Ihandle* ih, const char* group, const char* key, double value);
|
||||
IUP_API void IupConfigSetVariableDoubleId(Ihandle* ih, const char* group, const char* key, int id, double value);
|
||||
|
||||
IUP_API const char* IupConfigGetVariableStr(Ihandle* ih, const char* group, const char* key);
|
||||
IUP_API const char* IupConfigGetVariableStrId(Ihandle* ih, const char* group, const char* key, int id);
|
||||
IUP_API int IupConfigGetVariableInt(Ihandle* ih, const char* group, const char* key);
|
||||
IUP_API int IupConfigGetVariableIntId(Ihandle* ih, const char* group, const char* key, int id);
|
||||
IUP_API double IupConfigGetVariableDouble(Ihandle* ih, const char* group, const char* key);
|
||||
IUP_API double IupConfigGetVariableDoubleId(Ihandle* ih, const char* group, const char* key, int id);
|
||||
|
||||
IUP_API const char* IupConfigGetVariableStrDef(Ihandle* ih, const char* group, const char* key, const char* def);
|
||||
IUP_API const char* IupConfigGetVariableStrIdDef(Ihandle* ih, const char* group, const char* key, int id, const char* def);
|
||||
IUP_API int IupConfigGetVariableIntDef(Ihandle* ih, const char* group, const char* key, int def);
|
||||
IUP_API int IupConfigGetVariableIntIdDef(Ihandle* ih, const char* group, const char* key, int id, int def);
|
||||
IUP_API double IupConfigGetVariableDoubleDef(Ihandle* ih, const char* group, const char* key, double def);
|
||||
IUP_API double IupConfigGetVariableDoubleIdDef(Ihandle* ih, const char* group, const char* key, int id, double def);
|
||||
|
||||
IUP_API void IupConfigCopy(Ihandle* ih1, Ihandle* ih2, const char* exclude_prefix);
|
||||
|
||||
/****************************************************************/
|
||||
|
||||
IUP_API void IupConfigSetListVariable(Ihandle* ih, const char *group, const char* key, const char* value, int add);
|
||||
|
||||
IUP_API void IupConfigRecentInit(Ihandle* ih, Ihandle* menu, Icallback recent_cb, int max_recent);
|
||||
IUP_API void IupConfigRecentUpdate(Ihandle* ih, const char* filename);
|
||||
|
||||
IUP_API void IupConfigDialogShow(Ihandle* ih, Ihandle* dialog, const char* name);
|
||||
IUP_API void IupConfigDialogClosed(Ihandle* ih, Ihandle* dialog, const char* name);
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,83 @@
|
||||
#ifndef __IUP_EXPORT_H
|
||||
#define __IUP_EXPORT_H
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_IGNORE_THIS
|
||||
/** @cond DOXYGEN_SHOULD_IGNORE_THIS */
|
||||
|
||||
/* Mark the official functions */
|
||||
#ifndef IUP_API
|
||||
#ifdef IUP_BUILD_LIBRARY
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#define IUP_API EMSCRIPTEN_KEEPALIVE
|
||||
#elif WIN32
|
||||
#define IUP_API __declspec(dllexport)
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 4
|
||||
#define IUP_API __attribute__ ((visibility("default")))
|
||||
#else
|
||||
#define IUP_API
|
||||
#endif
|
||||
#else
|
||||
#define IUP_API
|
||||
#endif /* IUP_BUILD_LIBRARY */
|
||||
#endif /* IUP_API */
|
||||
|
||||
/* Mark the internal SDK functions (some not official but need to be exported) */
|
||||
#ifndef IUP_SDK_API
|
||||
#ifdef IUP_BUILD_LIBRARY
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#define IUP_SDK_API EMSCRIPTEN_KEEPALIVE
|
||||
#elif WIN32
|
||||
#define IUP_SDK_API __declspec(dllexport)
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 4
|
||||
#define IUP_SDK_API __attribute__ ((visibility("default")))
|
||||
#else
|
||||
#define IUP_SDK_API
|
||||
#endif
|
||||
#else
|
||||
#define IUP_SDK_API
|
||||
#endif /* IUP_BUILD_LIBRARY */
|
||||
#endif /* IUP_SDK_API */
|
||||
|
||||
/* Mark the driver functions that need to be exported */
|
||||
#ifndef IUP_DRV_API
|
||||
#ifdef IUP_BUILD_LIBRARY
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#define IUP_DRV_API EMSCRIPTEN_KEEPALIVE
|
||||
#elif WIN32
|
||||
#define IUP_DRV_API __declspec(dllexport)
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 4
|
||||
#define IUP_DRV_API __attribute__ ((visibility("default")))
|
||||
#else
|
||||
#define IUP_DRV_API
|
||||
#endif
|
||||
#else
|
||||
#define IUP_DRV_API
|
||||
#endif /* IUP_BUILD_LIBRARY */
|
||||
#endif /* IUP_DRV_API */
|
||||
|
||||
/* Mark the IupImageLib function, it does not have a header of its own */
|
||||
#ifndef IUPIMGLIB_API
|
||||
#ifdef IUPIMGLIB_BUILD_LIBRARY
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#define IUPIMGLIB_API EMSCRIPTEN_KEEPALIVE
|
||||
#elif WIN32
|
||||
#define IUPIMGLIB_API __declspec(dllexport)
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 4
|
||||
#define IUPIMGLIB_API __attribute__ ((visibility("default")))
|
||||
#else
|
||||
#define IUPIMGLIB_API
|
||||
#endif
|
||||
#else
|
||||
#define IUPIMGLIB_API
|
||||
#endif /* IUPIMGLIB_BUILD_LIBRARY */
|
||||
#endif /* IUPIMGLIB_API */
|
||||
|
||||
/** @endcond DOXYGEN_SHOULD_IGNORE_THIS */
|
||||
#endif /* DOXYGEN_SHOULD_IGNORE_THIS */
|
||||
|
||||
|
||||
#endif /* __IUP_EXPORT_H */
|
||||
@@ -0,0 +1,70 @@
|
||||
/** \file
|
||||
* \brief Plot component for Iup.
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef __IUP_MGLPLOT_H
|
||||
#define __IUP_MGLPLOT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Initialize IupMglPlot widget class */
|
||||
void IupMglPlotOpen(void);
|
||||
|
||||
/* Create an IupMglPlot widget instance */
|
||||
Ihandle* IupMglPlot(void);
|
||||
|
||||
/***********************************************/
|
||||
/* Additional API */
|
||||
|
||||
/* Linear Data Only */
|
||||
void IupMglPlotBegin(Ihandle *ih, int dim);
|
||||
void IupMglPlotAdd1D(Ihandle *ih, const char* name, double y);
|
||||
void IupMglPlotAdd2D(Ihandle *ih, double x, double y);
|
||||
void IupMglPlotAdd3D(Ihandle *ih, double x, double y, double z);
|
||||
int IupMglPlotEnd(Ihandle *ih);
|
||||
|
||||
/* Linear (dim=1,2,3), Planar (dim=1), Volumetric (dim=1) */
|
||||
int IupMglPlotNewDataSet(Ihandle *ih, int dim);
|
||||
|
||||
/* Linear Data Only */
|
||||
void IupMglPlotInsert1D(Ihandle* ih, int ds_index, int sample_index, const char** names, const double* y, int count);
|
||||
void IupMglPlotInsert2D(Ihandle* ih, int ds_index, int sample_index, const double* x, const double* y, int count);
|
||||
void IupMglPlotInsert3D(Ihandle* ih, int ds_index, int sample_index, const double* x, const double* y, const double* z, int count);
|
||||
|
||||
/* Linear Data Only */
|
||||
void IupMglPlotSet1D(Ihandle* ih, int ds_index, const char** names, const double* y, int count);
|
||||
void IupMglPlotSet2D(Ihandle* ih, int ds_index, const double* x, const double* y, int count);
|
||||
void IupMglPlotSet3D(Ihandle* ih, int ds_index, const double* x, const double* y, const double* z, int count);
|
||||
void IupMglPlotSetFormula(Ihandle* ih, int ds_index, const char* formulaX, const char* formulaY, const char* formulaZ, int count);
|
||||
|
||||
/* Linear (dim=1), Planar (dim=1), Volumetric (dim=1) */
|
||||
void IupMglPlotSetData(Ihandle* ih, int ds_index, const double* data, int count_x, int count_y, int count_z);
|
||||
void IupMglPlotLoadData(Ihandle* ih, int ds_index, const char* filename, int count_x, int count_y, int count_z);
|
||||
void IupMglPlotSetFromFormula(Ihandle* ih, int ds_index, const char* formula, int count_x, int count_y, int count_z);
|
||||
|
||||
/* Only inside callbacks */
|
||||
void IupMglPlotTransform(Ihandle* ih, double x, double y, double z, int *ix, int *iy);
|
||||
void IupMglPlotTransformTo(Ihandle* ih, int ix, int iy, double *x, double *y, double *z);
|
||||
|
||||
/* Only inside callbacks */
|
||||
void IupMglPlotDrawMark(Ihandle* ih, double x, double y, double z);
|
||||
void IupMglPlotDrawLine(Ihandle* ih, double x1, double y1, double z1, double x2, double y2, double z2);
|
||||
void IupMglPlotDrawText(Ihandle* ih, const char* text, double x, double y, double z);
|
||||
|
||||
void IupMglPlotPaintTo(Ihandle *ih, const char* format, int w, int h, double dpi, void *data);
|
||||
|
||||
/***********************************************/
|
||||
|
||||
/* Utility label for showing TeX labels */
|
||||
Ihandle* IupMglLabel(const char* title);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,70 @@
|
||||
/** \file
|
||||
* \brief Plot component for Iup.
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef __IUP_PLOT_H
|
||||
#define __IUP_PLOT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Initialize IupPlot widget class */
|
||||
void IupPlotOpen(void);
|
||||
|
||||
/* Create an IupPlot widget instance */
|
||||
Ihandle* IupPlot(void);
|
||||
|
||||
/***********************************************/
|
||||
/* Additional API */
|
||||
|
||||
void IupPlotBegin(Ihandle *ih, int strXdata);
|
||||
void IupPlotAdd(Ihandle *ih, double x, double y);
|
||||
void IupPlotAddStr(Ihandle *ih, const char* x, double y);
|
||||
void IupPlotAddSegment(Ihandle *ih, double x, double y);
|
||||
int IupPlotEnd(Ihandle *ih);
|
||||
|
||||
int IupPlotLoadData(Ihandle* ih, const char* filename, int strXdata);
|
||||
|
||||
/* available only when linking with "iupluaplot" */
|
||||
int IupPlotSetFormula(Ihandle* ih, int sample_count, const char* formula, const char* init);
|
||||
|
||||
void IupPlotInsert(Ihandle *ih, int ds_index, int sample_index, double x, double y);
|
||||
void IupPlotInsertStr(Ihandle *ih, int ds_index, int sample_index, const char* x, double y);
|
||||
void IupPlotInsertSegment(Ihandle *ih, int ds_index, int sample_index, double x, double y);
|
||||
|
||||
void IupPlotInsertStrSamples(Ihandle* ih, int ds_index, int sample_index, const char** x, double* y, int count);
|
||||
void IupPlotInsertSamples(Ihandle* ih, int ds_index, int sample_index, double *x, double *y, int count);
|
||||
|
||||
void IupPlotAddSamples(Ihandle* ih, int ds_index, double *x, double *y, int count);
|
||||
void IupPlotAddStrSamples(Ihandle* ih, int ds_index, const char** x, double* y, int count);
|
||||
|
||||
void IupPlotGetSample(Ihandle* ih, int ds_index, int sample_index, double *x, double *y);
|
||||
void IupPlotGetSampleStr(Ihandle* ih, int ds_index, int sample_index, const char* *x, double *y);
|
||||
int IupPlotGetSampleSelection(Ihandle* ih, int ds_index, int sample_index);
|
||||
double IupPlotGetSampleExtra(Ihandle* ih, int ds_index, int sample_index);
|
||||
void IupPlotSetSample(Ihandle* ih, int ds_index, int sample_index, double x, double y);
|
||||
void IupPlotSetSampleStr(Ihandle* ih, int ds_index, int sample_index, const char* x, double y);
|
||||
void IupPlotSetSampleSelection(Ihandle* ih, int ds_index, int sample_index, int selected);
|
||||
void IupPlotSetSampleExtra(Ihandle* ih, int ds_index, int sample_index, double extra);
|
||||
|
||||
void IupPlotTransform(Ihandle* ih, double x, double y, double *cnv_x, double *cnv_y);
|
||||
void IupPlotTransformTo(Ihandle* ih, double cnv_x, double cnv_y, double *x, double *y);
|
||||
|
||||
int IupPlotFindSample(Ihandle* ih, double cnv_x, double cnv_y, int *ds_index, int *sample_index);
|
||||
int IupPlotFindSegment(Ihandle* ih, double cnv_x, double cnv_y, int *ds_index, int *sample_index1, int *sample_index2);
|
||||
|
||||
struct _cdCanvas;
|
||||
|
||||
void IupPlotPaintTo(Ihandle *ih, struct _cdCanvas* cnv);
|
||||
|
||||
/***********************************************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,29 @@
|
||||
/** \file
|
||||
* \brief Scintilla control.
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef __IUP_SCINTILLA_H
|
||||
#define __IUP_SCINTILLA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
void IupScintillaOpen(void);
|
||||
|
||||
Ihandle *IupScintilla(void);
|
||||
Ihandle *IupScintillaDlg(void);
|
||||
|
||||
#ifdef SCINTILLA_H
|
||||
sptr_t IupScintillaSendMessage(Ihandle* ih, unsigned int iMessage, uptr_t wParam, sptr_t lParam);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,52 @@
|
||||
/** \file
|
||||
* \brief IUP API with explicit variable argument parameters.
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef __IUP_VARG_H
|
||||
#define __IUP_VARG_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "iup.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
IUP_API void IupLogV(const char* type, const char* format, va_list arglist);
|
||||
|
||||
IUP_API Ihandle* IupSetAttV(const char* handle_name, Ihandle* ih, const char* name, va_list arglist);
|
||||
|
||||
IUP_API void IupSetStrfV(Ihandle* ih, const char* name, const char* format, va_list arglist);
|
||||
IUP_API void IupSetStrfIdV(Ihandle* ih, const char* name, int id, const char* format, va_list arglist);
|
||||
IUP_API void IupSetStrfId2V(Ihandle* ih, const char* name, int lin, int col, const char* format, va_list arglist);
|
||||
|
||||
IUP_API Ihandle* IupSetCallbacksV(Ihandle* ih, const char *name, Icallback func, va_list arglist);
|
||||
|
||||
IUP_API Ihandle* IupCreateV(const char *classname, void* first, va_list arglist);
|
||||
IUP_API Ihandle* IupVboxV(Ihandle* child, va_list arglist);
|
||||
IUP_API Ihandle* IupZboxV(Ihandle* child, va_list arglist);
|
||||
IUP_API Ihandle* IupHboxV(Ihandle* child,va_list arglist);
|
||||
IUP_API Ihandle* IupNormalizerV(Ihandle* ih_first, va_list arglist);
|
||||
IUP_API Ihandle* IupCboxV(Ihandle* child, va_list arglist);
|
||||
IUP_API Ihandle* IupGridBoxV(Ihandle* child, va_list arglist);
|
||||
IUP_API Ihandle* IupMultiBoxV(Ihandle* child, va_list arglist);
|
||||
IUP_API Ihandle* IupMenuV(Ihandle* child,va_list arglist);
|
||||
IUP_API Ihandle* IupTabsV(Ihandle* child, va_list arglist);
|
||||
IUP_API Ihandle* IupFlatTabsV(Ihandle* child, va_list arglist);
|
||||
|
||||
IUP_API void IupMessageV(const char *title, const char *format, va_list arglist);
|
||||
IUP_API Ihandle* IupParamBoxV(Ihandle* param, va_list arglist);
|
||||
IUP_API int IupGetParamV(const char* title, Iparamcb action, void* user_data, const char* format, va_list arglist);
|
||||
|
||||
/* must include iupglcontrols before this file to enable this declaration */
|
||||
#ifdef __IUPGLCONTROLS_H
|
||||
#ifndef IUP_GLCONTROLS_API
|
||||
#define IUP_GLCONTROLS_API
|
||||
#endif
|
||||
IUP_GLCONTROLS_API Ihandle* IupGLCanvasBoxV(Ihandle* child, va_list arglist);
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,79 @@
|
||||
/** \file
|
||||
* \brief Contains all function pointer typedefs.
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef __IUPCBS_H
|
||||
#define __IUPCBS_H
|
||||
|
||||
struct _cdCanvas;
|
||||
|
||||
typedef int (*IFidle)(void); /* idle */
|
||||
typedef void (*IFentry)(void); /* entry */
|
||||
|
||||
typedef void (*IFi)(int); /* globalentermodal_cb, globalleavemodal_cb, */
|
||||
typedef void (*IFs)(char*); /* openurl_cb */
|
||||
typedef void (*IFii)(int, int); /* globalkeypress_cb */
|
||||
typedef void (*IFiis)(int, int, char*); /* globalmotion_cb, openfiles_cb */
|
||||
typedef void (*IFiiiis)(int, int, int, int, char*); /* globalbutton_cb */
|
||||
typedef void (*IFfiis)(float,int,int,char*); /* globalwheel_cb */
|
||||
typedef void (*IFvs)(void*, char*); /* handleadd_cb, handleremove_cb, imagecreate_cb, imagedestroy_cb */
|
||||
|
||||
typedef int (*IFn)(Ihandle*); /* default definition, same as Icallback */
|
||||
typedef int (*IFni)(Ihandle*, int); /* k_any, show_cb, toggle_action, spin_cb, branchopen_cb, branchclose_cb, executeleaf_cb, showrename_cb, rightclick_cb, extended_cb, height_cb, width_cb */
|
||||
typedef int (*IFnii)(Ihandle*, int, int); /* resize_cb, caret_cb, matrix_mousemove_cb, enteritem_cb, leaveitem_cb, scrolltop_cb, dropcheck_cb, selection_cb, select_cb, switch_cb, scrolling_cb, vspan_cb, hspan_cb */
|
||||
typedef int (*IFniii)(Ihandle*, int, int, int); /* trayclick_cb, edition_cb */
|
||||
typedef int (*IFniiii)(Ihandle*, int, int, int, int); /* dragdrop_cb */
|
||||
typedef int (*IFniiiiiiC)(Ihandle*, int, int, int, int, int, int, struct _cdCanvas*); /* draw_cb */
|
||||
typedef int (*IFniiiiii)(Ihandle*, int, int, int, int, int, int); /* OLD draw_cb */
|
||||
typedef int (*IFnsidv)(Ihandle*, char*, int, double, void*); /* postmessage_cb */
|
||||
|
||||
typedef int (*IFnff)(Ihandle*, float, float); /* canvas_action */
|
||||
typedef int (*IFniff)(Ihandle*,int,float,float); /* scroll_cb */
|
||||
typedef int (*IFnfiis)(Ihandle*,float,int,int,char*); /* wheel_cb */
|
||||
|
||||
typedef int (*IFnsVi)(Ihandle*, char*, void*, int); /* dragdata_cb */
|
||||
typedef int (*IFnsViii)(Ihandle*, char*, void*, int, int, int); /* dropdata_cb */
|
||||
typedef int (*IFnsiii)(Ihandle*, char*, int, int, int); /* dropfiles_cb */
|
||||
typedef int (*IFnssi)(Ihandle*, char*, char*, int); /* dragfilecreatename_cb */
|
||||
|
||||
typedef int (*IFnnii)(Ihandle*, Ihandle*, int, int); /* drop_cb */
|
||||
typedef int (*IFnn)(Ihandle*, Ihandle*); /* savemarkers_cb, restoremarkers_cb */
|
||||
typedef int (*IFnnn)(Ihandle*, Ihandle*, Ihandle*); /* tabchange_cb */
|
||||
typedef int (*IFnss)(Ihandle*, char *, char *); /* file_cb */
|
||||
typedef int (*IFns)(Ihandle*, char *); /* multiselect_cb */
|
||||
typedef int (*IFnsi)(Ihandle*, char *, int); /* copydata_cb */
|
||||
typedef int (*IFnis)(Ihandle*, int, char *); /* text_action, multiline_action, edit_cb, rename_cb */
|
||||
typedef int (*IFnsii)(Ihandle*, char*, int, int); /* list_action */
|
||||
typedef int (*IFniis)(Ihandle*, int, int, char*); /* motion_cb, click_cb, value_edit_cb */
|
||||
typedef int (*IFniiis)(Ihandle*, int, int, int, char*); /* touch_cb, dblclick_cb */
|
||||
typedef int (*IFniiiis)(Ihandle*, int, int, int, int, char*); /* button_cb, matrix_action, mousemotion_cb */
|
||||
typedef int (*IFniiiiiis)(Ihandle*, int, int, int, int, int, int, char*); /* mouseclick_cb */
|
||||
|
||||
typedef int (*IFnIi)(Ihandle*, int*, int); /* multiselection_cb, multiunselection_cb */
|
||||
typedef int (*IFnd)(Ihandle*, double); /* mousemove_cb, button_press_cb, button_release_cb */
|
||||
typedef int (*IFniiIII)(Ihandle*, int, int, int*, int*, int*); /* fgcolor_cb, bgcolor_cb */
|
||||
typedef int (*IFniinsii)(Ihandle*, int, int, Ihandle*, char*, int, int); /* dropselect_cb */
|
||||
typedef int (*IFnccc)(Ihandle*, unsigned char, unsigned char, unsigned char); /* drag_cb, change_cb */
|
||||
typedef int (*IFniIIII)(Ihandle*, int, int*, int*, int*, int*); /* multitouch_cb */
|
||||
|
||||
typedef int (*IFnC)(Ihandle*, struct _cdCanvas*); /* postdraw_cb, predraw_cb */
|
||||
typedef int (*IFniidd)(Ihandle*, int, int, double, double); /* delete_cb */
|
||||
typedef int (*IFniiddi)(Ihandle*, int, int, double, double, int); /* select_cb */
|
||||
typedef int (*IFniiddiddi)(Ihandle*, int, int, double, double, int, double, double, int); /* clicksegment_cb */
|
||||
typedef int (*IFniidds)(Ihandle*, int, int, double, double, char*); /* plotbutton_cb */
|
||||
typedef int (*IFndds)(Ihandle*, double, double, char*); /* plotmotion_cb */
|
||||
typedef int (*IFnssds)(Ihandle*, char*, char*, double, char*); /* plottickformat_cb */
|
||||
typedef int (*IFnni)(Ihandle*, Ihandle*, int);
|
||||
|
||||
typedef char* (*sIFnii)(Ihandle*, int, int); /* value_cb, font_cb */
|
||||
typedef char* (*sIFni)(Ihandle*, int); /* cell_cb */
|
||||
typedef char* (*sIFniis)(Ihandle*, int, int, char*); /* translatevalue_cb */
|
||||
|
||||
typedef double (*dIFnii)(Ihandle*, int, int); /* numericgetvalue_cb */
|
||||
typedef int (*IFniid)(Ihandle*, int, int, double); /* numericsetvalue_cb */
|
||||
|
||||
typedef void (*IFniiv)(Ihandle*, int, int, void*); /* android_onactivityresult_cb */
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,31 @@
|
||||
/** \file
|
||||
* \brief initializes dial, gauge, colorbrowser, colorbar controls.
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef __IUPCONTROLS_H
|
||||
#define __IUPCONTROLS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
int IupControlsOpen(void);
|
||||
|
||||
Ihandle* IupCells(void);
|
||||
Ihandle* IupMatrix(const char *action);
|
||||
Ihandle* IupMatrixList(void);
|
||||
Ihandle* IupMatrixEx(void);
|
||||
|
||||
/* available only when linking with "iupluamatrix" */
|
||||
void IupMatrixSetFormula(Ihandle* ih, int col, const char* formula, const char* init);
|
||||
void IupMatrixSetDynamic(Ihandle* ih, const char* init);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,683 @@
|
||||
/** \file
|
||||
* \brief Callbacks, Attributes and Attribute Values definitions.
|
||||
* Avoid using these definitions. Use the strings instead.
|
||||
*
|
||||
* See Copyright Notice in iup.h
|
||||
*/
|
||||
|
||||
#ifndef __IUPDEF_H
|
||||
#define __IUPDEF_H
|
||||
|
||||
/* ATTENTION: these are OLD definitions and they are NOT updated anymore since IUP 3.0 */
|
||||
/* Avoid using them, directly use the strings instead. */
|
||||
/* Define __IUPDEF_H to avoid the inclusion of this header */
|
||||
|
||||
#define IUP_RUN "RUN"
|
||||
#define IUP_ENGLISH "ENGLISH"
|
||||
#define IUP_PORTUGUESE "PORTUGUESE"
|
||||
#define IUP_SBH "SBH"
|
||||
#define IUP_SBV "SBV"
|
||||
|
||||
/************************************************************************/
|
||||
/* Callbacks */
|
||||
/************************************************************************/
|
||||
|
||||
#define IUP_IDLE_ACTION "IDLE_ACTION"
|
||||
|
||||
#define IUP_ACTION "ACTION"
|
||||
#define IUP_GETFOCUS_CB "GETFOCUS_CB"
|
||||
#define IUP_KILLFOCUS_CB "KILLFOCUS_CB"
|
||||
#define IUP_K_ANY "K_ANY"
|
||||
#define IUP_KEYPRESS_CB "KEYPRESS_CB"
|
||||
#define IUP_HELP_CB "HELP_CB"
|
||||
|
||||
#define IUP_SCROLL_CB "SCROLL_CB"
|
||||
#define IUP_RESIZE_CB "RESIZE_CB"
|
||||
#define IUP_MOTION_CB "MOTION_CB"
|
||||
#define IUP_BUTTON_CB "BUTTON_CB"
|
||||
#define IUP_ENTERWINDOW_CB "ENTERWINDOW_CB"
|
||||
#define IUP_LEAVEWINDOW_CB "LEAVEWINDOW_CB"
|
||||
#define IUP_WHEEL_CB "WHEEL_CB"
|
||||
|
||||
#define IUP_MASK_CB "MASK_CB"
|
||||
#define IUP_OPEN_CB "OPEN_CB"
|
||||
#define IUP_HIGHLIGHT_CB "HIGHLIGHT_CB"
|
||||
#define IUP_MENUCLOSE_CB "MENUCLOSE_CB"
|
||||
|
||||
#define IUP_MAP_CB "MAP_CB"
|
||||
#define IUP_CLOSE_CB "CLOSE_CB"
|
||||
#define IUP_SHOW_CB "SHOW_CB"
|
||||
|
||||
#define IUP_DROPFILES_CB "DROPFILES_CB"
|
||||
#define IUP_WOM_CB "WOM_CB"
|
||||
|
||||
/************************************************************************/
|
||||
/* Attributes */
|
||||
/************************************************************************/
|
||||
|
||||
#define IUP_DIRECTION "DIRECTION"
|
||||
#define IUP_ACTIVE "ACTIVE"
|
||||
#define IUP_BGCOLOR "BGCOLOR"
|
||||
#define IUP_FRAMECOLOR "FRAMECOLOR"
|
||||
#define IUP_FGCOLOR "FGCOLOR"
|
||||
#define IUP_COLOR "COLOR"
|
||||
#define IUP_WID "WID"
|
||||
#define IUP_SIZE "SIZE"
|
||||
#define IUP_RASTERSIZE "RASTERSIZE"
|
||||
#define IUP_TITLE "TITLE"
|
||||
#define IUP_VALUE "VALUE"
|
||||
#define IUP_VISIBLE "VISIBLE"
|
||||
#define IUP_FONT "FONT"
|
||||
#define IUP_TIP "TIP"
|
||||
#define IUP_EXPAND "EXPAND"
|
||||
#define IUP_SEPARATOR "SEPARATOR"
|
||||
|
||||
#define IUP_HOTSPOT "HOTSPOT"
|
||||
#define IUP_HEIGHT "HEIGHT"
|
||||
#define IUP_WIDTH "WIDTH"
|
||||
|
||||
#define IUP_KEY "KEY"
|
||||
|
||||
#define IUP_MULTIPLE "MULTIPLE"
|
||||
#define IUP_DROPDOWN "DROPDOWN"
|
||||
#define IUP_VISIBLE_ITEMS "VISIBLE_ITEMS"
|
||||
|
||||
#define IUP_MARGIN "MARGIN"
|
||||
#define IUP_GAP "GAP"
|
||||
#define IUP_ALIGNMENT "ALIGNMENT"
|
||||
|
||||
#define IUP_IMAGE "IMAGE"
|
||||
#define IUP_IMINACTIVE "IMINACTIVE"
|
||||
#define IUP_IMPRESS "IMPRESS"
|
||||
#define IUP_WIN_SAVEBITS "WIN_SAVEBITS"
|
||||
|
||||
#define IUP_NC "NC"
|
||||
#define IUP_MASK "MASK"
|
||||
|
||||
#define IUP_APPEND "APPEND"
|
||||
#define IUP_BORDER "BORDER"
|
||||
|
||||
#define IUP_CARET "CARET"
|
||||
#define IUP_SELECTION "SELECTION"
|
||||
#define IUP_SELECTEDTEXT "SELECTEDTEXT"
|
||||
#define IUP_INSERT "INSERT"
|
||||
|
||||
#define IUP_CONID "CONID"
|
||||
#define IUP_CURSOR "CURSOR"
|
||||
|
||||
#define IUP_ICON "ICON"
|
||||
#define IUP_MENUBOX "MENUBOX"
|
||||
#define IUP_MINBOX "MINBOX"
|
||||
#define IUP_MAXBOX "MAXBOX"
|
||||
#define IUP_RESIZE "RESIZE"
|
||||
#define IUP_MENU "MENU"
|
||||
#define IUP_STARTFOCUS "STARTFOCUS"
|
||||
#define IUP_PARENTDIALOG "PARENTDIALOG"
|
||||
#define IUP_SHRINK "SHRINK"
|
||||
#define IUP_DEFAULTENTER "DEFAULTENTER"
|
||||
#define IUP_DEFAULTESC "DEFAULTESC"
|
||||
#define IUP_X "X"
|
||||
#define IUP_Y "Y"
|
||||
#define IUP_TOOLBOX "TOOLBOX"
|
||||
#define IUP_CONTROL "CONTROL"
|
||||
#define IUP_READONLY "READONLY"
|
||||
|
||||
#define IUP_SCROLLBAR "SCROLLBAR"
|
||||
#define IUP_POSY "POSY"
|
||||
#define IUP_POSX "POSX"
|
||||
#define IUP_DX "DX"
|
||||
#define IUP_DY "DY"
|
||||
#define IUP_XMAX "XMAX"
|
||||
#define IUP_XMIN "XMIN"
|
||||
#define IUP_YMAX "YMAX"
|
||||
#define IUP_YMIN "YMIN"
|
||||
|
||||
#define IUP_RED "255 0 0"
|
||||
#define IUP_GREEN "0 255 0"
|
||||
#define IUP_BLUE "0 0 255"
|
||||
|
||||
#define IUP_MIN "MIN"
|
||||
#define IUP_MAX "MAX"
|
||||
|
||||
#define IUP_TIME "TIME"
|
||||
#define IUP_DRAG "DRAG"
|
||||
#define IUP_DROP "DROP"
|
||||
#define IUP_REPAINT "REPAINT"
|
||||
#define IUP_TOPMOST "TOPMOST"
|
||||
#define IUP_CLIPCHILDREN "CLIPCHILDREN"
|
||||
|
||||
#define IUP_DIALOGTYPE "DIALOGTYPE"
|
||||
#define IUP_FILE "FILE"
|
||||
#define IUP_MULTIPLEFILES "MULTIPLEFILES"
|
||||
#define IUP_FILTER "FILTER"
|
||||
#define IUP_FILTERUSED "FILTERUSED"
|
||||
#define IUP_FILTERINFO "FILTERINFO"
|
||||
#define IUP_EXTFILTER "EXTFILTER"
|
||||
#define IUP_DIRECTORY "DIRECTORY"
|
||||
#define IUP_ALLOWNEW "ALLOWNEW"
|
||||
#define IUP_NOOVERWRITEPROMPT "NOOVERWRITEPROMPT"
|
||||
#define IUP_NOCHANGEDIR "NOCHANGEDIR"
|
||||
#define IUP_FILEEXIST "FILEEXIST"
|
||||
#define IUP_STATUS "STATUS"
|
||||
|
||||
#define IUP_LOCKLOOP "LOCKLOOP"
|
||||
#define IUP_SYSTEM "SYSTEM"
|
||||
#define IUP_DRIVER "DRIVER"
|
||||
#define IUP_SCREENSIZE "SCREENSIZE"
|
||||
#define IUP_SYSTEMLANGUAGE "SYSTEMLANGUAGE"
|
||||
#define IUP_COMPUTERNAME "COMPUTERNAME"
|
||||
#define IUP_USERNAME "USERNAME"
|
||||
|
||||
#define IUP_OPEN "OPEN"
|
||||
#define IUP_SAVE "SAVE"
|
||||
#define IUP_DIR "DIR"
|
||||
|
||||
#define IUP_HORIZONTAL "HORIZONTAL"
|
||||
#define IUP_VERTICAL "VERTICAL"
|
||||
|
||||
/************************************************************************/
|
||||
/* Attribute Values */
|
||||
/************************************************************************/
|
||||
|
||||
#define IUP_YES "YES"
|
||||
#define IUP_NO "NO"
|
||||
#define IUP_ON "ON"
|
||||
#define IUP_OFF "OFF"
|
||||
|
||||
#define IUP_ACENTER "ACENTER"
|
||||
#define IUP_ALEFT "ALEFT"
|
||||
#define IUP_ARIGHT "ARIGHT"
|
||||
#define IUP_ATOP "ATOP"
|
||||
#define IUP_ABOTTOM "ABOTTOM"
|
||||
|
||||
#define IUP_NORTH "NORTH"
|
||||
#define IUP_SOUTH "SOUTH"
|
||||
#define IUP_WEST "WEST"
|
||||
#define IUP_EAST "EAST"
|
||||
#define IUP_NE "NE"
|
||||
#define IUP_SE "SE"
|
||||
#define IUP_NW "NW"
|
||||
#define IUP_SW "SW"
|
||||
|
||||
#define IUP_FULLSCREEN "FULLSCREEN"
|
||||
#define IUP_FULL "FULL"
|
||||
#define IUP_HALF "HALF"
|
||||
#define IUP_THIRD "THIRD"
|
||||
#define IUP_QUARTER "QUARTER"
|
||||
#define IUP_EIGHTH "EIGHTH"
|
||||
|
||||
#define IUP_ARROW "ARROW"
|
||||
#define IUP_BUSY "BUSY"
|
||||
#define IUP_RESIZE_N "RESIZE_N"
|
||||
#define IUP_RESIZE_S "RESIZE_S"
|
||||
#define IUP_RESIZE_E "RESIZE_E"
|
||||
#define IUP_RESIZE_W "RESIZE_W"
|
||||
#define IUP_RESIZE_NE "RESIZE_NE"
|
||||
#define IUP_RESIZE_NW "RESIZE_NW"
|
||||
#define IUP_RESIZE_SE "RESIZE_SE"
|
||||
#define IUP_RESIZE_SW "RESIZE_SW"
|
||||
#define IUP_MOVE "MOVE"
|
||||
#define IUP_HAND "HAND"
|
||||
#define IUP_NONE "NONE"
|
||||
#define IUP_IUP "IUP"
|
||||
#define IUP_CROSS "CROSS"
|
||||
#define IUP_PEN "PEN"
|
||||
#define IUP_TEXT "TEXT"
|
||||
#define IUP_RESIZE_C "RESIZE_C"
|
||||
#define IUP_OPENHAND "OPENHAND"
|
||||
|
||||
/************************************************************************/
|
||||
/* Keys */
|
||||
/************************************************************************/
|
||||
|
||||
#define IUP_K_exclam "K_exclam"
|
||||
#define IUP_K_quotedbl "K_quotedbl"
|
||||
#define IUP_K_numbersign "K_numbersign"
|
||||
#define IUP_K_dollar "K_dollar"
|
||||
#define IUP_K_percent "K_percent"
|
||||
#define IUP_K_ampersand "K_ampersand"
|
||||
#define IUP_K_quoteright "K_quoteright"
|
||||
#define IUP_K_parentleft "K_parentleft"
|
||||
#define IUP_K_parentright "K_parentright"
|
||||
#define IUP_K_asterisk "K_asterisk"
|
||||
#define IUP_K_plus "K_plus"
|
||||
#define IUP_K_comma "K_comma"
|
||||
#define IUP_K_minus "K_minus"
|
||||
#define IUP_K_period "K_period"
|
||||
#define IUP_K_slash "K_slash"
|
||||
#define IUP_K_0 "K_0"
|
||||
#define IUP_K_1 "K_1"
|
||||
#define IUP_K_2 "K_2"
|
||||
#define IUP_K_3 "K_3"
|
||||
#define IUP_K_4 "K_4"
|
||||
#define IUP_K_5 "K_5"
|
||||
#define IUP_K_6 "K_6"
|
||||
#define IUP_K_7 "K_7"
|
||||
#define IUP_K_8 "K_8"
|
||||
#define IUP_K_9 "K_9"
|
||||
#define IUP_K_colon "K_colon"
|
||||
#define IUP_K_semicolon "K_semicolon "
|
||||
#define IUP_K_less "K_less"
|
||||
#define IUP_K_equal "K_equal"
|
||||
#define IUP_K_greater "K_greater"
|
||||
#define IUP_K_question "K_question"
|
||||
#define IUP_K_at "K_at"
|
||||
#define IUP_K_A "K_A"
|
||||
#define IUP_K_B "K_B"
|
||||
#define IUP_K_C "K_C"
|
||||
#define IUP_K_D "K_D"
|
||||
#define IUP_K_E "K_E"
|
||||
#define IUP_K_F "K_F"
|
||||
#define IUP_K_G "K_G"
|
||||
#define IUP_K_H "K_H"
|
||||
#define IUP_K_I "K_I"
|
||||
#define IUP_K_J "K_J"
|
||||
#define IUP_K_K "K_K"
|
||||
#define IUP_K_L "K_L"
|
||||
#define IUP_K_M "K_M"
|
||||
#define IUP_K_N "K_N"
|
||||
#define IUP_K_O "K_O"
|
||||
#define IUP_K_P "K_P"
|
||||
#define IUP_K_Q "K_Q"
|
||||
#define IUP_K_R "K_R"
|
||||
#define IUP_K_S "K_S"
|
||||
#define IUP_K_T "K_T"
|
||||
#define IUP_K_U "K_U"
|
||||
#define IUP_K_V "K_V"
|
||||
#define IUP_K_W "K_W"
|
||||
#define IUP_K_X "K_X"
|
||||
#define IUP_K_Y "K_Y"
|
||||
#define IUP_K_Z "K_Z"
|
||||
#define IUP_K_bracketleft "K_bracketleft"
|
||||
#define IUP_K_backslash "K_backslash"
|
||||
#define IUP_K_bracketright "K_bracketright"
|
||||
#define IUP_K_circum "K_circum"
|
||||
#define IUP_K_underscore "K_underscore"
|
||||
#define IUP_K_quoteleft "K_quoteleft"
|
||||
#define IUP_K_a "K_a"
|
||||
#define IUP_K_b "K_b"
|
||||
#define IUP_K_c "K_c"
|
||||
#define IUP_K_d "K_d"
|
||||
#define IUP_K_e "K_e"
|
||||
#define IUP_K_f "K_f"
|
||||
#define IUP_K_g "K_g"
|
||||
#define IUP_K_h "K_h"
|
||||
#define IUP_K_i "K_i"
|
||||
#define IUP_K_j "K_j"
|
||||
#define IUP_K_k "K_k"
|
||||
#define IUP_K_l "K_l"
|
||||
#define IUP_K_m "K_m"
|
||||
#define IUP_K_n "K_n"
|
||||
#define IUP_K_o "K_o"
|
||||
#define IUP_K_p "K_p"
|
||||
#define IUP_K_q "K_q"
|
||||
#define IUP_K_r "K_r"
|
||||
#define IUP_K_s "K_s"
|
||||
#define IUP_K_t "K_t"
|
||||
#define IUP_K_u "K_u"
|
||||
#define IUP_K_v "K_v"
|
||||
#define IUP_K_w "K_w"
|
||||
#define IUP_K_x "K_x"
|
||||
#define IUP_K_y "K_y"
|
||||
#define IUP_K_z "K_z"
|
||||
#define IUP_K_braceleft "K_braceleft"
|
||||
#define IUP_K_bar "K_bar"
|
||||
#define IUP_K_braceright "K_braceright"
|
||||
#define IUP_K_tilde "K_tilde"
|
||||
|
||||
#define IUP_K_cA "K_cA"
|
||||
#define IUP_K_cB "K_cB"
|
||||
#define IUP_K_cC "K_cC"
|
||||
#define IUP_K_cD "K_cD"
|
||||
#define IUP_K_cE "K_cE"
|
||||
#define IUP_K_cF "K_cF"
|
||||
#define IUP_K_cG "K_cG"
|
||||
#define IUP_K_cJ "K_cJ"
|
||||
#define IUP_K_cK "K_cK"
|
||||
#define IUP_K_cL "K_cL"
|
||||
#define IUP_K_cN "K_cN"
|
||||
#define IUP_K_cO "K_cO"
|
||||
#define IUP_K_cP "K_cP"
|
||||
#define IUP_K_cQ "K_cQ"
|
||||
#define IUP_K_cR "K_cR"
|
||||
#define IUP_K_cS "K_cS"
|
||||
#define IUP_K_cT "K_cT"
|
||||
#define IUP_K_cU "K_cU"
|
||||
#define IUP_K_cV "K_cV"
|
||||
#define IUP_K_cW "K_cW"
|
||||
#define IUP_K_cX "K_cX"
|
||||
#define IUP_K_cY "K_cY"
|
||||
#define IUP_K_cZ "K_cZ"
|
||||
#define IUP_K_mA "K_mA"
|
||||
#define IUP_K_mB "K_mB"
|
||||
#define IUP_K_mC "K_mC"
|
||||
#define IUP_K_mD "K_mD"
|
||||
#define IUP_K_mE "K_mE"
|
||||
#define IUP_K_mF "K_mF"
|
||||
#define IUP_K_mG "K_mG"
|
||||
#define IUP_K_mH "K_mH"
|
||||
#define IUP_K_mI "K_mI"
|
||||
#define IUP_K_mJ "K_mJ"
|
||||
#define IUP_K_mK "K_mK"
|
||||
#define IUP_K_mL "K_mL"
|
||||
#define IUP_K_mM "K_mM"
|
||||
#define IUP_K_mN "K_mN"
|
||||
#define IUP_K_mO "K_mO"
|
||||
#define IUP_K_mP "K_mP"
|
||||
#define IUP_K_mQ "K_mQ"
|
||||
#define IUP_K_mR "K_mR"
|
||||
#define IUP_K_mS "K_mS"
|
||||
#define IUP_K_mT "K_mT"
|
||||
#define IUP_K_mU "K_mU"
|
||||
#define IUP_K_mV "K_mV"
|
||||
#define IUP_K_mW "K_mW"
|
||||
#define IUP_K_mX "K_mX"
|
||||
#define IUP_K_mY "K_mY"
|
||||
#define IUP_K_mZ "K_mZ"
|
||||
#define IUP_K_BS "K_BS"
|
||||
#define IUP_K_TAB "K_TAB"
|
||||
#define IUP_K_CR "K_CR"
|
||||
#define IUP_K_SP "K_SP"
|
||||
#define IUP_K_ESC "K_ESC"
|
||||
#define IUP_K_sCR "K_sCR"
|
||||
#define IUP_K_sTAB "K_sTAB"
|
||||
#define IUP_K_cTAB "K_cTAB"
|
||||
#define IUP_K_mTAB "K_mTAB"
|
||||
#define IUP_K_HOME "K_HOME"
|
||||
#define IUP_K_UP "K_UP"
|
||||
#define IUP_K_PGUP "K_PGUP"
|
||||
#define IUP_K_LEFT "K_LEFT"
|
||||
#define IUP_K_RIGHT "K_RIGHT"
|
||||
#define IUP_K_END "K_END"
|
||||
#define IUP_K_DOWN "K_DOWN"
|
||||
#define IUP_K_PGDN "K_PGDN"
|
||||
#define IUP_K_MIDDLE "K_MIDDLE"
|
||||
#define IUP_K_INS "K_INS"
|
||||
#define IUP_K_DEL "K_DEL"
|
||||
#define IUP_K_sHOME "K_sHOME"
|
||||
#define IUP_K_sUP "K_sUP"
|
||||
#define IUP_K_sPGUP "K_sPGUP"
|
||||
#define IUP_K_sLEFT "K_sLEFT"
|
||||
#define IUP_K_sRIGHT "K_sRIGHT"
|
||||
#define IUP_K_sEND "K_sEND"
|
||||
#define IUP_K_sDOWN "K_sDOWN"
|
||||
#define IUP_K_sPGDN "K_sPGDN"
|
||||
#define IUP_K_cHOME "K_cHOME"
|
||||
#define IUP_K_cPGUP "K_cPGUP"
|
||||
#define IUP_K_cLEFT "K_cLEFT"
|
||||
#define IUP_K_cRIGHT "K_cRIGHT"
|
||||
#define IUP_K_cEND "K_cEND"
|
||||
#define IUP_K_cPGDN "K_cPGDN"
|
||||
#define IUP_K_cUP "K_cUP"
|
||||
#define IUP_K_cDOWN "K_cDOWN"
|
||||
#define IUP_K_cMIDDLE "K_cMIDDLE"
|
||||
#define IUP_K_cINS "K_cINS"
|
||||
#define IUP_K_cDEL "K_cDEL"
|
||||
#define IUP_K_mHOME "K_mHOME"
|
||||
#define IUP_K_mPGUP "K_mPGUP"
|
||||
#define IUP_K_mLEFT "K_mLEFT"
|
||||
#define IUP_K_mRIGHT "K_mRIGHT"
|
||||
#define IUP_K_mEND "K_mEND"
|
||||
#define IUP_K_mPGDN "K_mPGDN"
|
||||
#define IUP_K_mUP "K_mUP"
|
||||
#define IUP_K_mDOWN "K_mDOWN"
|
||||
#define IUP_K_mINS "K_mINS"
|
||||
#define IUP_K_mDEL "K_mDEL"
|
||||
#define IUP_K_F1 "K_F1"
|
||||
#define IUP_K_F2 "K_F2"
|
||||
#define IUP_K_F3 "K_F3"
|
||||
#define IUP_K_F4 "K_F4"
|
||||
#define IUP_K_F5 "K_F5"
|
||||
#define IUP_K_F6 "K_F6"
|
||||
#define IUP_K_F7 "K_F7"
|
||||
#define IUP_K_F8 "K_F8"
|
||||
#define IUP_K_F9 "K_F9"
|
||||
#define IUP_K_F10 "K_F10"
|
||||
#define IUP_K_F11 "K_F11"
|
||||
#define IUP_K_F12 "K_F12"
|
||||
#define IUP_K_sF1 "K_sF1"
|
||||
#define IUP_K_sF2 "K_sF2"
|
||||
#define IUP_K_sF3 "K_sF3"
|
||||
#define IUP_K_sF4 "K_sF4"
|
||||
#define IUP_K_sF5 "K_sF5"
|
||||
#define IUP_K_sF6 "K_sF6"
|
||||
#define IUP_K_sF7 "K_sF7"
|
||||
#define IUP_K_sF8 "K_sF8"
|
||||
#define IUP_K_sF9 "K_sF9"
|
||||
#define IUP_K_sF10 "K_sF10"
|
||||
#define IUP_K_sF11 "K_sF11"
|
||||
#define IUP_K_sF12 "K_sF12"
|
||||
#define IUP_K_cF1 "K_cF1"
|
||||
#define IUP_K_cF2 "K_cF2"
|
||||
#define IUP_K_cF3 "K_cF3"
|
||||
#define IUP_K_cF4 "K_cF4"
|
||||
#define IUP_K_cF5 "K_cF5"
|
||||
#define IUP_K_cF6 "K_cF6"
|
||||
#define IUP_K_cF7 "K_cF7"
|
||||
#define IUP_K_cF8 "K_cF8"
|
||||
#define IUP_K_cF9 "K_cF9"
|
||||
#define IUP_K_cF10 "K_cF10"
|
||||
#define IUP_K_cF11 "K_cF11"
|
||||
#define IUP_K_cF12 "K_cF12"
|
||||
#define IUP_K_mF1 "K_mF1"
|
||||
#define IUP_K_mF2 "K_mF2"
|
||||
#define IUP_K_mF3 "K_mF3"
|
||||
#define IUP_K_mF4 "K_mF4"
|
||||
#define IUP_K_mF5 "K_mF5"
|
||||
#define IUP_K_mF6 "K_mF6"
|
||||
#define IUP_K_mF7 "K_mF7"
|
||||
#define IUP_K_mF8 "K_mF8"
|
||||
#define IUP_K_mF9 "K_mF9"
|
||||
#define IUP_K_mF10 "K_mF10"
|
||||
#define IUP_K_m1 "K_m1"
|
||||
#define IUP_K_m2 "K_m2"
|
||||
#define IUP_K_m3 "K_m3"
|
||||
#define IUP_K_m4 "K_m4"
|
||||
#define IUP_K_m5 "K_m5"
|
||||
#define IUP_K_m6 "K_m6"
|
||||
#define IUP_K_m7 "K_m7"
|
||||
#define IUP_K_m8 "K_m8"
|
||||
#define IUP_K_m9 "K_m9"
|
||||
#define IUP_K_m0 "K_m0"
|
||||
|
||||
/************/
|
||||
/* Colorbar */
|
||||
/************/
|
||||
|
||||
#define IUP_NUM_PARTS "NUM_PARTS"
|
||||
#define IUP_NUM_CELLS "NUM_CELLS"
|
||||
#define IUP_CELL "CELL"
|
||||
#define IUP_PREVIEW_SIZE "PREVIEW_SIZE"
|
||||
#define IUP_SHOW_PREVIEW "SHOW_PREVIEW"
|
||||
#define IUP_SHOW_SECONDARY "SHOW_SECONDARY"
|
||||
#define IUP_PRIMARY_CELL "PRIMARY_CELL"
|
||||
#define IUP_SECONDARY_CELL "SECONDARY_CELL"
|
||||
#define IUP_ORIENTATION "ORIENTATION"
|
||||
#define IUP_SQUARED "SQUARED"
|
||||
#define IUP_SHADOWED "SHADOWED"
|
||||
#define IUP_BUFFERIZE "BUFFERIZE"
|
||||
#define IUP_TRANSPARENCY "TRANSPARENCY"
|
||||
#define IUP_CELL_CB "CELL_CB"
|
||||
#define IUP_EXTENDED_CB "EXTENDED_CB"
|
||||
#define IUP_SELECT_CB "SELECT_CB"
|
||||
#define IUP_SWITCH_CB "SWITCH_CB"
|
||||
#define IUP_VERTICAL "VERTICAL"
|
||||
#define IUP_HORIZONTAL "HORIZONTAL"
|
||||
|
||||
/************/
|
||||
/* Cells */
|
||||
/************/
|
||||
|
||||
#define IUP_ALL "ALL"
|
||||
#define IUP_BOXED "BOXED"
|
||||
#define IUP_CLIPPED "CLIPPED"
|
||||
#define IUP_TRANSPARENT "TRANSPARENT"
|
||||
#define IUP_NON_SCROLLABLE_LINES "NON_SCROLLABLE_LINES"
|
||||
#define IUP_NON_SCROLLABLE_COLS "NON_SCROLLABLE_COLS"
|
||||
#define IUP_ORIGIN "ORIGIN"
|
||||
#define IUP_NO_COLOR "NO_COLOR"
|
||||
#define IUP_FIRST_LINE "FIRST_LINE"
|
||||
#define IUP_FIRST_COL "FIRST_COL"
|
||||
#define IUP_DOUBLE_BUFFER "DOUBLE_BUFFER"
|
||||
#define IUP_LIMITS "LIMITS"
|
||||
#define IUP_CANVAS "CANVAS"
|
||||
#define IUP_IMAGE_CANVAS "IMAGE_CANVAS"
|
||||
#define IUP_FULL_VISIBLE "FULL_VISIBLE"
|
||||
#define IUP_MOUSECLICK_CB "MOUSECLICK_CB"
|
||||
#define IUP_MOUSEMOTION_CB "MOUSEMOTION_CB"
|
||||
#define IUP_DRAW_CB "DRAW_CB"
|
||||
#define IUP_WIDTH_CB "WIDTH_CB"
|
||||
#define IUP_HEIGHT_CB "HEIGHT_CB"
|
||||
#define IUP_NLINES_CB "NLINES_CB"
|
||||
#define IUP_NCOLS_CB "NCOLS_CB"
|
||||
#define IUP_HSPAN_CB "HSPAN_CB"
|
||||
#define IUP_VSPAN_CB "VSPAN_CB"
|
||||
#define IUP_SCROLLING_CB "SCROLLING_CB"
|
||||
|
||||
/*****************/
|
||||
/* ColorBrowser */
|
||||
/*****************/
|
||||
|
||||
#define IUP_RGB "RGB"
|
||||
#define IUP_CHANGE_CB "CHANGE_CB"
|
||||
#define IUP_DRAG_CB "DRAG_CB"
|
||||
|
||||
/*****************/
|
||||
/* Val */
|
||||
/*****************/
|
||||
|
||||
#define ICTL_MOUSEMOVE_CB "MOUSEMOVE_CB"
|
||||
#define ICTL_BUTTON_PRESS_CB "BUTTON_PRESS_CB"
|
||||
#define ICTL_BUTTON_RELEASE_CB "BUTTON_RELEASE_CB"
|
||||
#define ICTL_HORIZONTAL "HORIZONTAL"
|
||||
#define ICTL_VERTICAL "VERTICAL"
|
||||
#define ICTL_SHOWTICKS "SHOWTICKS"
|
||||
|
||||
/*****************/
|
||||
/* Tabs */
|
||||
/*****************/
|
||||
|
||||
#define ICTL_TOP "TOP"
|
||||
#define ICTL_BOTTOM "BOTTOM"
|
||||
#define ICTL_LEFT "LEFT"
|
||||
#define ICTL_RIGHT "RIGHT"
|
||||
#define ICTL_TABTYPE "TABTYPE"
|
||||
#define ICTL_TABTITLE "TABTITLE"
|
||||
#define ICTL_TABSIZE "TABSIZE"
|
||||
#define ICTL_TABCHANGE_CB "TABCHANGE_CB"
|
||||
#define ICTL_FONT "FONT"
|
||||
#define ICTL_FONT_ACTIVE "FONT_ACTIVE"
|
||||
#define ICTL_FONT_INACTIVE "FONT_INACTIVE"
|
||||
|
||||
/*****************/
|
||||
/* Gauge */
|
||||
/*****************/
|
||||
|
||||
#define ICTL_SHOW_TEXT "SHOW_TEXT"
|
||||
#define ICTL_DASHED "DASHED"
|
||||
#define ICTL_MARGIN "MARGIN"
|
||||
#define ICTL_TEXT "TEXT"
|
||||
|
||||
/*****************/
|
||||
/* Dial */
|
||||
/*****************/
|
||||
|
||||
#define ICTL_DENSITY "DENSITY"
|
||||
#define ICTL_HORIZONTAL "HORIZONTAL"
|
||||
#define ICTL_VERTICAL "VERTICAL"
|
||||
#define ICTL_CIRCULAR "CIRCULAR"
|
||||
#define ICTL_UNIT "UNIT"
|
||||
|
||||
/*****************/
|
||||
/* Matrix */
|
||||
/*****************/
|
||||
|
||||
#define IUP_ENTERITEM_CB "ENTERITEM_CB"
|
||||
#define IUP_LEAVEITEM_CB "LEAVEITEM_CB"
|
||||
#define IUP_EDITION_CB "EDITION_CB"
|
||||
#define IUP_CLICK_CB "CLICK_CB"
|
||||
#define IUP_DROP_CB "DROP_CB"
|
||||
#define IUP_DROPSELECT_CB "DROPSELECT_CB"
|
||||
#define IUP_DROPCHECK_CB "DROPCHECK_CB"
|
||||
#define IUP_SCROLL_CB "SCROLL_CB"
|
||||
#define IUP_VALUE_CB "VALUE_CB"
|
||||
#define IUP_VALUE_EDIT_CB "VALUE_EDIT_CB"
|
||||
#define IUP_FIELD_CB "FIELD_CB"
|
||||
#define IUP_RESIZEMATRIX "RESIZEMATRIX"
|
||||
#define IUP_ADDLIN "ADDLIN"
|
||||
#define IUP_ADDCOL "ADDCOL"
|
||||
#define IUP_DELLIN "DELLIN"
|
||||
#define IUP_DELCOL "DELCOL"
|
||||
#define IUP_NUMLIN "NUMLIN"
|
||||
#define IUP_NUMCOL "NUMCOL"
|
||||
#define IUP_NUMLIN_VISIBLE "NUMLIN_VISIBLE"
|
||||
#define IUP_NUMCOL_VISIBLE "NUMCOL_VISIBLE"
|
||||
#define IUP_MARKED "MARKED"
|
||||
#define IUP_WIDTHDEF "WIDTHDEF"
|
||||
#define IUP_HEIGHTDEF "HEIGHTDEF"
|
||||
#define IUP_AREA "AREA"
|
||||
#define IUP_MARK_MODE "MARK_MODE"
|
||||
#define IUP_LIN "LIN"
|
||||
#define IUP_COL "COL"
|
||||
#define IUP_LINCOL "LINCOL"
|
||||
#define IUP_CELL "CELL"
|
||||
#define IUP_EDIT_MODE "EDIT_MODE"
|
||||
#define IUP_FOCUS_CELL "FOCUS_CELL"
|
||||
#define IUP_ORIGIN "ORIGIN"
|
||||
#define IUP_REDRAW "REDRAW"
|
||||
#define IUP_PREVIOUSVALUE "PREVIOUSVALUE"
|
||||
#define IUP_MOUSEMOVE_CB "MOUSEMOVE_CB"
|
||||
|
||||
/*****************/
|
||||
/* Tree */
|
||||
/*****************/
|
||||
|
||||
#define IUP_ADDLEAF "ADDLEAF"
|
||||
#define IUP_ADDBRANCH "ADDBRANCH"
|
||||
#define IUP_DELNODE "DELNODE"
|
||||
#define IUP_IMAGELEAF "IMAGELEAF"
|
||||
#define IUP_IMAGEBRANCHCOLLAPSED "IMAGEBRANCHCOLLAPSED"
|
||||
#define IUP_IMAGEBRANCHEXPANDED "IMAGEBRANCHEXPANDED"
|
||||
#define IUP_IMAGEEXPANDED "IMAGEEXPANDED"
|
||||
#define IUP_KIND "KIND"
|
||||
#define IUP_PARENT "PARENT"
|
||||
#define IUP_DEPTH "DEPTH"
|
||||
#define IUP_MARKED "MARKED"
|
||||
#define IUP_ADDEXPANDED "ADDEXPANDED"
|
||||
#define IUP_CTRL "CTRL"
|
||||
#define IUP_SHIFT "SHIFT"
|
||||
#define IUP_STATE "STATE"
|
||||
#define IUP_STARTING "STARTING"
|
||||
#define IUP_LEAF "LEAF"
|
||||
#define IUP_BRANCH "BRANCH"
|
||||
#define IUP_SELECTED "SELECTED"
|
||||
#define IUP_CHILDREN "CHILDREN"
|
||||
#define IUP_MARKED "MARKED"
|
||||
#define IUP_ROOT "ROOT"
|
||||
#define IUP_LAST "LAST"
|
||||
#define IUP_PGUP "PGUP"
|
||||
#define IUP_PGDN "PGDN"
|
||||
#define IUP_NEXT "NEXT"
|
||||
#define IUP_PREVIOUS "PREVIOUS"
|
||||
#define IUP_INVERT "INVERT"
|
||||
#define IUP_BLOCK "BLOCK"
|
||||
#define IUP_CLEARALL "CLEARALL"
|
||||
#define IUP_MARKALL "MARKALL"
|
||||
#define IUP_INVERTALL "INVERTALL"
|
||||
#define IUP_REDRAW "REDRAW"
|
||||
#define IUP_COLLAPSED "COLLAPSED"
|
||||
#define IUP_EXPANDED "EXPANDED"
|
||||
#define IUP_SELECTION_CB "SELECTION_CB"
|
||||
#define IUP_BRANCHOPEN_CB "BRANCHOPEN_CB"
|
||||
#define IUP_BRANCHCLOSE_CB "BRANCHCLOSE_CB"
|
||||
#define IUP_RIGHTCLICK_CB "RIGHTCLICK_CB"
|
||||
#define IUP_EXECUTELEAF_CB "EXECUTELEAF_CB"
|
||||
#define IUP_RENAMENODE_CB "RENAMENODE_CB"
|
||||
#define IUP_IMGLEAF "IMGLEAF"
|
||||
#define IUP_IMGCOLLAPSED "IMGCOLLAPSED"
|
||||
#define IUP_IMGEXPANDED "IMGEXPANDED"
|
||||
#define IUP_IMGBLANK "IMGBLANK"
|
||||
#define IUP_IMGPAPER "IMGPAPER"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/** \file
|
||||
* \brief Canvas Draw API
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef __IUPDRAW_H
|
||||
#define __IUPDRAW_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* all functions can be used only in IUP canvas and inside the ACTION callback */
|
||||
|
||||
IUP_API void IupDrawBegin(Ihandle* ih);
|
||||
IUP_API void IupDrawEnd(Ihandle* ih);
|
||||
|
||||
/* all functions can be called only between calls to Begin and End */
|
||||
|
||||
IUP_API void IupDrawSetClipRect(Ihandle* ih, int x1, int y1, int x2, int y2);
|
||||
IUP_API void IupDrawGetClipRect(Ihandle* ih, int *x1, int *y1, int *x2, int *y2);
|
||||
IUP_API void IupDrawResetClip(Ihandle* ih);
|
||||
|
||||
/* color controlled by the attribute DRAWCOLOR */
|
||||
/* line style or fill controlled by the attribute DRAWSTYLE */
|
||||
|
||||
IUP_API void IupDrawParentBackground(Ihandle* ih);
|
||||
IUP_API void IupDrawLine(Ihandle* ih, int x1, int y1, int x2, int y2);
|
||||
IUP_API void IupDrawRectangle(Ihandle* ih, int x1, int y1, int x2, int y2);
|
||||
IUP_API void IupDrawArc(Ihandle* ih, int x1, int y1, int x2, int y2, double a1, double a2);
|
||||
IUP_API void IupDrawPolygon(Ihandle* ih, int* points, int count);
|
||||
IUP_API void IupDrawText(Ihandle* ih, const char* text, int len, int x, int y, int w, int h);
|
||||
IUP_API void IupDrawImage(Ihandle* ih, const char* name, int x, int y, int w, int h);
|
||||
IUP_API void IupDrawSelectRect(Ihandle* ih, int x1, int y1, int x2, int y2);
|
||||
IUP_API void IupDrawFocusRect(Ihandle* ih, int x1, int y1, int x2, int y2);
|
||||
|
||||
IUP_API void IupDrawGetSize(Ihandle* ih, int *w, int *h);
|
||||
IUP_API void IupDrawGetTextSize(Ihandle* ih, const char* text, int len, int *w, int *h);
|
||||
IUP_API void IupDrawGetImageInfo(const char* name, int *w, int *h, int *bpp);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,21 @@
|
||||
/** \file
|
||||
* \brief IupDraw CD driver
|
||||
*
|
||||
* See Copyright Notice in iup.h
|
||||
*/
|
||||
|
||||
#ifndef __CD_IUPDRAW_H
|
||||
#define __CD_IUPDRAW_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
cdContext* cdContextIupDraw(void);
|
||||
#define CD_IUPDRAW cdContextIupDraw()
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ifndef __CD_IUPDRAW_ */
|
||||
@@ -0,0 +1,24 @@
|
||||
/** \file
|
||||
* \brief New FileDlg (Windows Only).
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef __IUPFILEDLG_H
|
||||
#define __IUPFILEDLG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* the only exported function,
|
||||
once called it will replace regular IupFileDlg */
|
||||
|
||||
int IupNewFileDlgOpen(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,97 @@
|
||||
/** \file
|
||||
* \brief OpenGL canvas for Iup.
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef __IUPGL_H
|
||||
#define __IUPGL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Attributes
|
||||
** To set the appropriate visual (pixel format) the following
|
||||
** attributes may be specified. Their values should be set
|
||||
** before the canvas is mapped to the scrren.
|
||||
** After mapping, changing their values has no effect.
|
||||
*/
|
||||
#ifndef IUP_BUFFER /* IUP_SINGLE (defaut) or IUP_DOUBLE */
|
||||
#define IUP_BUFFER "BUFFER"
|
||||
#endif
|
||||
#ifndef IUP_STEREO /* IUP_NO (defaut) or IUP_YES */
|
||||
#define IUP_STEREO "STEREO"
|
||||
#endif
|
||||
#ifndef IUP_BUFFER_SIZE /* Number of bits if index mode */
|
||||
#define IUP_BUFFER_SIZE "BUFFER_SIZE"
|
||||
#endif
|
||||
#ifndef IUP_RED_SIZE /* Number of red bits */
|
||||
#define IUP_RED_SIZE "RED_SIZE"
|
||||
#endif
|
||||
#ifndef IUP_GREEN_SIZE /* Number of green bits */
|
||||
#define IUP_GREEN_SIZE "GREEN_SIZE"
|
||||
#endif
|
||||
#ifndef IUP_BLUE_SIZE /* Number of blue bits */
|
||||
#define IUP_BLUE_SIZE "BLUE_SIZE"
|
||||
#endif
|
||||
#ifndef IUP_ALPHA_SIZE /* Number of alpha bits */
|
||||
#define IUP_ALPHA_SIZE "ALPHA_SIZE"
|
||||
#endif
|
||||
#ifndef IUP_DEPTH_SIZE /* Number of bits in depth buffer */
|
||||
#define IUP_DEPTH_SIZE "DEPTH_SIZE"
|
||||
#endif
|
||||
#ifndef IUP_STENCIL_SIZE /* Number of bits in stencil buffer */
|
||||
#define IUP_STENCIL_SIZE "STENCIL_SIZE"
|
||||
#endif
|
||||
#ifndef IUP_ACCUM_RED_SIZE /* Number of red bits in accum. buffer */
|
||||
#define IUP_ACCUM_RED_SIZE "ACCUM_RED_SIZE"
|
||||
#endif
|
||||
#ifndef IUP_ACCUM_GREEN_SIZE /* Number of green bits in accum. buffer */
|
||||
#define IUP_ACCUM_GREEN_SIZE "ACCUM_GREEN_SIZE"
|
||||
#endif
|
||||
#ifndef IUP_ACCUM_BLUE_SIZE /* Number of blue bits in accum. buffer */
|
||||
#define IUP_ACCUM_BLUE_SIZE "ACCUM_BLUE_SIZE"
|
||||
#endif
|
||||
#ifndef IUP_ACCUM_ALPHA_SIZE /* Number of alpha bits in accum. buffer */
|
||||
#define IUP_ACCUM_ALPHA_SIZE "ACCUM_ALPHA_SIZE"
|
||||
#endif
|
||||
|
||||
|
||||
/* Attribute values */
|
||||
#ifndef IUP_DOUBLE
|
||||
#define IUP_DOUBLE "DOUBLE"
|
||||
#endif
|
||||
#ifndef IUP_SINGLE
|
||||
#define IUP_SINGLE "SINGLE"
|
||||
#endif
|
||||
#ifndef IUP_INDEX
|
||||
#define IUP_INDEX "INDEX"
|
||||
#endif
|
||||
#ifndef IUP_RGBA
|
||||
#define IUP_RGBA "RGBA"
|
||||
#endif
|
||||
#ifndef IUP_YES
|
||||
#define IUP_YES "YES"
|
||||
#endif
|
||||
#ifndef IUP_NO
|
||||
#define IUP_NO "NO"
|
||||
#endif
|
||||
|
||||
void IupGLCanvasOpen(void);
|
||||
|
||||
Ihandle *IupGLCanvas(const char *action);
|
||||
Ihandle* IupGLBackgroundBox(Ihandle* child);
|
||||
|
||||
void IupGLMakeCurrent(Ihandle* ih);
|
||||
int IupGLIsCurrent(Ihandle* ih);
|
||||
void IupGLSwapBuffers(Ihandle* ih);
|
||||
void IupGLPalette(Ihandle* ih, int index, float r, float g, float b);
|
||||
void IupGLUseFont(Ihandle* ih, int first, int count, int list_base);
|
||||
void IupGLWait(int gl);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,47 @@
|
||||
/** \file
|
||||
* \brief GL Controls.
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef __IUPGLCONTROLS_H
|
||||
#define __IUPGLCONTROLS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
int IupGLControlsOpen(void);
|
||||
|
||||
Ihandle* IupGLCanvasBoxv(Ihandle** children);
|
||||
Ihandle* IupGLCanvasBox(Ihandle* child, ...);
|
||||
|
||||
Ihandle* IupGLSubCanvas(void);
|
||||
|
||||
Ihandle* IupGLLabel(const char* title);
|
||||
Ihandle* IupGLSeparator(void);
|
||||
Ihandle* IupGLButton(const char* title);
|
||||
Ihandle* IupGLToggle(const char* title);
|
||||
Ihandle* IupGLLink(const char *url, const char * title);
|
||||
Ihandle* IupGLProgressBar(void);
|
||||
Ihandle* IupGLVal(void);
|
||||
Ihandle* IupGLFrame(Ihandle* child);
|
||||
Ihandle* IupGLExpander(Ihandle* child);
|
||||
Ihandle* IupGLScrollBox(Ihandle* child);
|
||||
Ihandle* IupGLSizeBox(Ihandle* child);
|
||||
Ihandle* IupGLText(void);
|
||||
|
||||
|
||||
/* Utilities */
|
||||
void IupGLDrawImage(Ihandle* ih, const char* name, int x, int y, int active);
|
||||
void IupGLDrawText(Ihandle* ih, const char* str, int len, int x, int y);
|
||||
void IupGLDrawGetTextSize(Ihandle* ih, const char* str, int *w, int *h);
|
||||
void IupGLDrawGetImageInfo(const char* name, int *w, int *h, int *bpp);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,36 @@
|
||||
/** \file
|
||||
* \brief Utilities using IM
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef __IUPIM_H
|
||||
#define __IUPIM_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
void IupImOpen(void); /* optional */
|
||||
|
||||
Ihandle* IupLoadImage(const char* filename);
|
||||
int IupSaveImage(Ihandle* ih, const char* filename, const char* format);
|
||||
|
||||
Ihandle* IupLoadAnimation(const char* filename);
|
||||
Ihandle* IupLoadAnimationFrames(const char** filename_list, int file_count);
|
||||
|
||||
#ifdef __IM_IMAGE_H
|
||||
imImage* IupGetNativeHandleImage(void* handle);
|
||||
void* IupGetImageNativeHandle(const imImage* image);
|
||||
|
||||
Ihandle* IupImageFromImImage(const imImage* image);
|
||||
imImage* IupImageToImImage(Ihandle* iup_image);
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,533 @@
|
||||
/** \file
|
||||
* \brief Keyboard Keys definitions.
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef __IUPKEY_H
|
||||
#define __IUPKEY_H
|
||||
|
||||
/* from 32 to 126, all character sets are equal,
|
||||
the key code is the same as the ASCii character code. */
|
||||
|
||||
#define K_SP ' ' /* 32 (0x20) */
|
||||
#define K_exclam '!' /* 33 */
|
||||
#define K_quotedbl '\"' /* 34 */
|
||||
#define K_numbersign '#' /* 35 */
|
||||
#define K_dollar '$' /* 36 */
|
||||
#define K_percent '%' /* 37 */
|
||||
#define K_ampersand '&' /* 38 */
|
||||
#define K_apostrophe '\'' /* 39 */
|
||||
#define K_parentleft '(' /* 40 */
|
||||
#define K_parentright ')' /* 41 */
|
||||
#define K_asterisk '*' /* 42 */
|
||||
#define K_plus '+' /* 43 */
|
||||
#define K_comma ',' /* 44 */
|
||||
#define K_minus '-' /* 45 */
|
||||
#define K_period '.' /* 46 */
|
||||
#define K_slash '/' /* 47 */
|
||||
#define K_0 '0' /* 48 (0x30) */
|
||||
#define K_1 '1' /* 49 */
|
||||
#define K_2 '2' /* 50 */
|
||||
#define K_3 '3' /* 51 */
|
||||
#define K_4 '4' /* 52 */
|
||||
#define K_5 '5' /* 53 */
|
||||
#define K_6 '6' /* 54 */
|
||||
#define K_7 '7' /* 55 */
|
||||
#define K_8 '8' /* 56 */
|
||||
#define K_9 '9' /* 57 */
|
||||
#define K_colon ':' /* 58 */
|
||||
#define K_semicolon ';' /* 59 */
|
||||
#define K_less '<' /* 60 */
|
||||
#define K_equal '=' /* 61 */
|
||||
#define K_greater '>' /* 62 */
|
||||
#define K_question '?' /* 63 */
|
||||
#define K_at '@' /* 64 */
|
||||
#define K_A 'A' /* 65 (0x41) */
|
||||
#define K_B 'B' /* 66 */
|
||||
#define K_C 'C' /* 67 */
|
||||
#define K_D 'D' /* 68 */
|
||||
#define K_E 'E' /* 69 */
|
||||
#define K_F 'F' /* 70 */
|
||||
#define K_G 'G' /* 71 */
|
||||
#define K_H 'H' /* 72 */
|
||||
#define K_I 'I' /* 73 */
|
||||
#define K_J 'J' /* 74 */
|
||||
#define K_K 'K' /* 75 */
|
||||
#define K_L 'L' /* 76 */
|
||||
#define K_M 'M' /* 77 */
|
||||
#define K_N 'N' /* 78 */
|
||||
#define K_O 'O' /* 79 */
|
||||
#define K_P 'P' /* 80 */
|
||||
#define K_Q 'Q' /* 81 */
|
||||
#define K_R 'R' /* 82 */
|
||||
#define K_S 'S' /* 83 */
|
||||
#define K_T 'T' /* 84 */
|
||||
#define K_U 'U' /* 85 */
|
||||
#define K_V 'V' /* 86 */
|
||||
#define K_W 'W' /* 87 */
|
||||
#define K_X 'X' /* 88 */
|
||||
#define K_Y 'Y' /* 89 */
|
||||
#define K_Z 'Z' /* 90 */
|
||||
#define K_bracketleft '[' /* 91 */
|
||||
#define K_backslash '\\' /* 92 */
|
||||
#define K_bracketright ']' /* 93 */
|
||||
#define K_circum '^' /* 94 */
|
||||
#define K_underscore '_' /* 95 */
|
||||
#define K_grave '`' /* 96 */
|
||||
#define K_a 'a' /* 97 (0x61) */
|
||||
#define K_b 'b' /* 98 */
|
||||
#define K_c 'c' /* 99 */
|
||||
#define K_d 'd' /* 100 */
|
||||
#define K_e 'e' /* 101 */
|
||||
#define K_f 'f' /* 102 */
|
||||
#define K_g 'g' /* 103 */
|
||||
#define K_h 'h' /* 104 */
|
||||
#define K_i 'i' /* 105 */
|
||||
#define K_j 'j' /* 106 */
|
||||
#define K_k 'k' /* 107 */
|
||||
#define K_l 'l' /* 108 */
|
||||
#define K_m 'm' /* 109 */
|
||||
#define K_n 'n' /* 110 */
|
||||
#define K_o 'o' /* 111 */
|
||||
#define K_p 'p' /* 112 */
|
||||
#define K_q 'q' /* 113 */
|
||||
#define K_r 'r' /* 114 */
|
||||
#define K_s 's' /* 115 */
|
||||
#define K_t 't' /* 116 */
|
||||
#define K_u 'u' /* 117 */
|
||||
#define K_v 'v' /* 118 */
|
||||
#define K_w 'w' /* 119 */
|
||||
#define K_x 'x' /* 120 */
|
||||
#define K_y 'y' /* 121 */
|
||||
#define K_z 'z' /* 122 */
|
||||
#define K_braceleft '{' /* 123 */
|
||||
#define K_bar '|' /* 124 */
|
||||
#define K_braceright '}' /* 125 */
|
||||
#define K_tilde '~' /* 126 (0x7E) */
|
||||
|
||||
/* Printable ASCii keys */
|
||||
|
||||
#define iup_isprint(_c) ((_c) > 31 && (_c) < 127)
|
||||
|
||||
/* also define the escape sequences that have keys associated */
|
||||
|
||||
#define K_BS '\b' /* 8 */
|
||||
#define K_TAB '\t' /* 9 */
|
||||
#define K_LF '\n' /* 10 (0x0A) not a real key, is a combination of CR with a modifier, just to document */
|
||||
#define K_CR '\r' /* 13 (0x0D) */
|
||||
|
||||
/* backward compatible definitions */
|
||||
|
||||
#define K_quoteleft K_grave
|
||||
#define K_quoteright K_apostrophe
|
||||
#define isxkey iup_isXkey
|
||||
|
||||
/* IUP Extended Key Codes, range start at 128 */
|
||||
|
||||
#define iup_isXkey(_c) ((_c) >= 128)
|
||||
|
||||
/* These use the same definition as X11 and GDK.
|
||||
This also means that any X11 or GDK definition can also be used. */
|
||||
|
||||
#define K_PAUSE 0xFF13
|
||||
#define K_ESC 0xFF1B
|
||||
#define K_HOME 0xFF50
|
||||
#define K_LEFT 0xFF51
|
||||
#define K_UP 0xFF52
|
||||
#define K_RIGHT 0xFF53
|
||||
#define K_DOWN 0xFF54
|
||||
#define K_PGUP 0xFF55
|
||||
#define K_PGDN 0xFF56
|
||||
#define K_END 0xFF57
|
||||
#define K_MIDDLE 0xFF0B
|
||||
#define K_Print 0xFF61
|
||||
#define K_INS 0xFF63
|
||||
#define K_Menu 0xFF67
|
||||
#define K_DEL 0xFFFF
|
||||
#define K_F1 0xFFBE
|
||||
#define K_F2 0xFFBF
|
||||
#define K_F3 0xFFC0
|
||||
#define K_F4 0xFFC1
|
||||
#define K_F5 0xFFC2
|
||||
#define K_F6 0xFFC3
|
||||
#define K_F7 0xFFC4
|
||||
#define K_F8 0xFFC5
|
||||
#define K_F9 0xFFC6
|
||||
#define K_F10 0xFFC7
|
||||
#define K_F11 0xFFC8
|
||||
#define K_F12 0xFFC9
|
||||
#define K_F13 0xFFCA
|
||||
#define K_F14 0xFFCB
|
||||
#define K_F15 0xFFCC
|
||||
#define K_F16 0xFFCD
|
||||
#define K_F17 0xFFCE
|
||||
#define K_F18 0xFFCF
|
||||
#define K_F19 0xFFD0
|
||||
#define K_F20 0xFFD1
|
||||
|
||||
/* no Shift/Ctrl/Alt */
|
||||
#define K_LSHIFT 0xFFE1
|
||||
#define K_RSHIFT 0xFFE2
|
||||
#define K_LCTRL 0xFFE3
|
||||
#define K_RCTRL 0xFFE4
|
||||
#define K_LALT 0xFFE9
|
||||
#define K_RALT 0xFFEA
|
||||
|
||||
#define K_NUM 0xFF7F
|
||||
#define K_SCROLL 0xFF14
|
||||
#define K_CAPS 0xFFE5
|
||||
|
||||
/* Mac clear button. Value randomly picked trying to avoid clashing with an existing value. */
|
||||
#define K_CLEAR 0xFFD2
|
||||
/* Help button if anybody has it. Value randomly picked trying to avoid clashing with an existing value. */
|
||||
#define K_HELP 0xFFD3
|
||||
|
||||
/* Also, these are the same as the Latin-1 definition */
|
||||
|
||||
#define K_ccedilla 0x00E7
|
||||
#define K_Ccedilla 0x00C7
|
||||
#define K_acute 0x00B4 /* no Shift/Ctrl/Alt */
|
||||
#define K_diaeresis 0x00A8
|
||||
|
||||
/******************************************************/
|
||||
/* Modifiers use last 4 bits. Since IUP 3.9 */
|
||||
/* These modifiers definitions are specific to IUP */
|
||||
/******************************************************/
|
||||
|
||||
#define iup_isShiftXkey(_c) (((_c) & 0x10000000) != 0)
|
||||
#define iup_isCtrlXkey(_c) (((_c) & 0x20000000) != 0)
|
||||
#define iup_isAltXkey(_c) (((_c) & 0x40000000) != 0)
|
||||
#define iup_isSysXkey(_c) (((_c) & 0x80000000) != 0)
|
||||
|
||||
#define iup_XkeyBase(_c) ((_c) & 0x0FFFFFFF)
|
||||
#define iup_XkeyShift(_c) ((_c) | 0x10000000) /* Shift */
|
||||
#define iup_XkeyCtrl(_c) ((_c) | 0x20000000) /* Ctrl */
|
||||
#define iup_XkeyAlt(_c) ((_c) | 0x40000000) /* Alt */
|
||||
#define iup_XkeySys(_c) ((_c) | 0x80000000) /* Sys (Win or Apple) - notice that using "int" will display a negative value */
|
||||
|
||||
/* These definitions are here for backward compatibility
|
||||
and to simplify some key combination usage.
|
||||
But since IUP 3.9, modifiers can be combined with any key
|
||||
and they can be mixed together. */
|
||||
|
||||
#define K_sHOME iup_XkeyShift(K_HOME )
|
||||
#define K_sUP iup_XkeyShift(K_UP )
|
||||
#define K_sPGUP iup_XkeyShift(K_PGUP )
|
||||
#define K_sLEFT iup_XkeyShift(K_LEFT )
|
||||
#define K_sMIDDLE iup_XkeyShift(K_MIDDLE )
|
||||
#define K_sRIGHT iup_XkeyShift(K_RIGHT )
|
||||
#define K_sEND iup_XkeyShift(K_END )
|
||||
#define K_sDOWN iup_XkeyShift(K_DOWN )
|
||||
#define K_sPGDN iup_XkeyShift(K_PGDN )
|
||||
#define K_sINS iup_XkeyShift(K_INS )
|
||||
#define K_sDEL iup_XkeyShift(K_DEL )
|
||||
#define K_sSP iup_XkeyShift(K_SP )
|
||||
#define K_sTAB iup_XkeyShift(K_TAB )
|
||||
#define K_sCR iup_XkeyShift(K_CR )
|
||||
#define K_sBS iup_XkeyShift(K_BS )
|
||||
#define K_sPAUSE iup_XkeyShift(K_PAUSE )
|
||||
#define K_sESC iup_XkeyShift(K_ESC )
|
||||
#define K_sCLEAR iup_XkeyShift(K_CLEAR )
|
||||
#define K_sF1 iup_XkeyShift(K_F1 )
|
||||
#define K_sF2 iup_XkeyShift(K_F2 )
|
||||
#define K_sF3 iup_XkeyShift(K_F3 )
|
||||
#define K_sF4 iup_XkeyShift(K_F4 )
|
||||
#define K_sF5 iup_XkeyShift(K_F5 )
|
||||
#define K_sF6 iup_XkeyShift(K_F6 )
|
||||
#define K_sF7 iup_XkeyShift(K_F7 )
|
||||
#define K_sF8 iup_XkeyShift(K_F8 )
|
||||
#define K_sF9 iup_XkeyShift(K_F9 )
|
||||
#define K_sF10 iup_XkeyShift(K_F10 )
|
||||
#define K_sF11 iup_XkeyShift(K_F11 )
|
||||
#define K_sF12 iup_XkeyShift(K_F12 )
|
||||
#define K_sF13 iup_XkeyShift(K_F13 )
|
||||
#define K_sF14 iup_XkeyShift(K_F14 )
|
||||
#define K_sF15 iup_XkeyShift(K_F15 )
|
||||
#define K_sF16 iup_XkeyShift(K_F16 )
|
||||
#define K_sF17 iup_XkeyShift(K_F17 )
|
||||
#define K_sF18 iup_XkeyShift(K_F18 )
|
||||
#define K_sF19 iup_XkeyShift(K_F19 )
|
||||
#define K_sF20 iup_XkeyShift(K_F20 )
|
||||
#define K_sPrint iup_XkeyShift(K_Print )
|
||||
#define K_sMenu iup_XkeyShift(K_Menu )
|
||||
|
||||
#define K_cHOME iup_XkeyCtrl(K_HOME )
|
||||
#define K_cUP iup_XkeyCtrl(K_UP )
|
||||
#define K_cPGUP iup_XkeyCtrl(K_PGUP )
|
||||
#define K_cLEFT iup_XkeyCtrl(K_LEFT )
|
||||
#define K_cMIDDLE iup_XkeyCtrl(K_MIDDLE )
|
||||
#define K_cRIGHT iup_XkeyCtrl(K_RIGHT )
|
||||
#define K_cEND iup_XkeyCtrl(K_END )
|
||||
#define K_cDOWN iup_XkeyCtrl(K_DOWN )
|
||||
#define K_cPGDN iup_XkeyCtrl(K_PGDN )
|
||||
#define K_cINS iup_XkeyCtrl(K_INS )
|
||||
#define K_cDEL iup_XkeyCtrl(K_DEL )
|
||||
#define K_cSP iup_XkeyCtrl(K_SP )
|
||||
#define K_cTAB iup_XkeyCtrl(K_TAB )
|
||||
#define K_cCR iup_XkeyCtrl(K_CR )
|
||||
#define K_cBS iup_XkeyCtrl(K_BS )
|
||||
#define K_cPAUSE iup_XkeyCtrl(K_PAUSE )
|
||||
#define K_cESC iup_XkeyCtrl(K_ESC )
|
||||
#define K_cCLEAR iup_XkeyCtrl(K_CLEAR )
|
||||
#define K_cCcedilla iup_XkeyCtrl(K_Ccedilla)
|
||||
#define K_cF1 iup_XkeyCtrl(K_F1 )
|
||||
#define K_cF2 iup_XkeyCtrl(K_F2 )
|
||||
#define K_cF3 iup_XkeyCtrl(K_F3 )
|
||||
#define K_cF4 iup_XkeyCtrl(K_F4 )
|
||||
#define K_cF5 iup_XkeyCtrl(K_F5 )
|
||||
#define K_cF6 iup_XkeyCtrl(K_F6 )
|
||||
#define K_cF7 iup_XkeyCtrl(K_F7 )
|
||||
#define K_cF8 iup_XkeyCtrl(K_F8 )
|
||||
#define K_cF9 iup_XkeyCtrl(K_F9 )
|
||||
#define K_cF10 iup_XkeyCtrl(K_F10 )
|
||||
#define K_cF11 iup_XkeyCtrl(K_F11 )
|
||||
#define K_cF12 iup_XkeyCtrl(K_F12 )
|
||||
#define K_cF13 iup_XkeyCtrl(K_F13 )
|
||||
#define K_cF14 iup_XkeyCtrl(K_F14 )
|
||||
#define K_cF15 iup_XkeyCtrl(K_F15 )
|
||||
#define K_cF16 iup_XkeyCtrl(K_F16 )
|
||||
#define K_cF17 iup_XkeyCtrl(K_F17 )
|
||||
#define K_cF18 iup_XkeyCtrl(K_F18 )
|
||||
#define K_cF19 iup_XkeyCtrl(K_F19 )
|
||||
#define K_cF20 iup_XkeyCtrl(K_F20 )
|
||||
#define K_cPrint iup_XkeyCtrl(K_Print )
|
||||
#define K_cMenu iup_XkeyCtrl(K_Menu )
|
||||
|
||||
#define K_mHOME iup_XkeyAlt(K_HOME )
|
||||
#define K_mUP iup_XkeyAlt(K_UP )
|
||||
#define K_mPGUP iup_XkeyAlt(K_PGUP )
|
||||
#define K_mLEFT iup_XkeyAlt(K_LEFT )
|
||||
#define K_mMIDDLE iup_XkeyAlt(K_MIDDLE )
|
||||
#define K_mRIGHT iup_XkeyAlt(K_RIGHT )
|
||||
#define K_mEND iup_XkeyAlt(K_END )
|
||||
#define K_mDOWN iup_XkeyAlt(K_DOWN )
|
||||
#define K_mPGDN iup_XkeyAlt(K_PGDN )
|
||||
#define K_mINS iup_XkeyAlt(K_INS )
|
||||
#define K_mDEL iup_XkeyAlt(K_DEL )
|
||||
#define K_mSP iup_XkeyAlt(K_SP )
|
||||
#define K_mTAB iup_XkeyAlt(K_TAB )
|
||||
#define K_mCR iup_XkeyAlt(K_CR )
|
||||
#define K_mBS iup_XkeyAlt(K_BS )
|
||||
#define K_mPAUSE iup_XkeyAlt(K_PAUSE )
|
||||
#define K_mESC iup_XkeyAlt(K_ESC )
|
||||
#define K_mCLEAR iup_XkeyAlt(K_CLEAR )
|
||||
#define K_mCcedilla iup_XkeyAlt(K_Ccedilla)
|
||||
#define K_mF1 iup_XkeyAlt(K_F1 )
|
||||
#define K_mF2 iup_XkeyAlt(K_F2 )
|
||||
#define K_mF3 iup_XkeyAlt(K_F3 )
|
||||
#define K_mF4 iup_XkeyAlt(K_F4 )
|
||||
#define K_mF5 iup_XkeyAlt(K_F5 )
|
||||
#define K_mF6 iup_XkeyAlt(K_F6 )
|
||||
#define K_mF7 iup_XkeyAlt(K_F7 )
|
||||
#define K_mF8 iup_XkeyAlt(K_F8 )
|
||||
#define K_mF9 iup_XkeyAlt(K_F9 )
|
||||
#define K_mF10 iup_XkeyAlt(K_F10 )
|
||||
#define K_mF11 iup_XkeyAlt(K_F11 )
|
||||
#define K_mF12 iup_XkeyAlt(K_F12 )
|
||||
#define K_mF13 iup_XkeyAlt(K_F13 )
|
||||
#define K_mF14 iup_XkeyAlt(K_F14 )
|
||||
#define K_mF15 iup_XkeyAlt(K_F15 )
|
||||
#define K_mF16 iup_XkeyAlt(K_F16 )
|
||||
#define K_mF17 iup_XkeyAlt(K_F17 )
|
||||
#define K_mF18 iup_XkeyAlt(K_F18 )
|
||||
#define K_mF19 iup_XkeyAlt(K_F19 )
|
||||
#define K_mF20 iup_XkeyAlt(K_F20 )
|
||||
#define K_mPrint iup_XkeyAlt(K_Print )
|
||||
#define K_mMenu iup_XkeyAlt(K_Menu )
|
||||
|
||||
#define K_yHOME iup_XkeySys(K_HOME )
|
||||
#define K_yUP iup_XkeySys(K_UP )
|
||||
#define K_yPGUP iup_XkeySys(K_PGUP )
|
||||
#define K_yLEFT iup_XkeySys(K_LEFT )
|
||||
#define K_yMIDDLE iup_XkeySys(K_MIDDLE )
|
||||
#define K_yRIGHT iup_XkeySys(K_RIGHT )
|
||||
#define K_yEND iup_XkeySys(K_END )
|
||||
#define K_yDOWN iup_XkeySys(K_DOWN )
|
||||
#define K_yPGDN iup_XkeySys(K_PGDN )
|
||||
#define K_yINS iup_XkeySys(K_INS )
|
||||
#define K_yDEL iup_XkeySys(K_DEL )
|
||||
#define K_ySP iup_XkeySys(K_SP )
|
||||
#define K_yTAB iup_XkeySys(K_TAB )
|
||||
#define K_yCR iup_XkeySys(K_CR )
|
||||
#define K_yBS iup_XkeySys(K_BS )
|
||||
#define K_yPAUSE iup_XkeySys(K_PAUSE )
|
||||
#define K_yESC iup_XkeySys(K_ESC )
|
||||
#define K_yCLEAR iup_XkeySys(K_CLEAR )
|
||||
#define K_yCcedilla iup_XkeySys(K_Ccedilla)
|
||||
#define K_yF1 iup_XkeySys(K_F1 )
|
||||
#define K_yF2 iup_XkeySys(K_F2 )
|
||||
#define K_yF3 iup_XkeySys(K_F3 )
|
||||
#define K_yF4 iup_XkeySys(K_F4 )
|
||||
#define K_yF5 iup_XkeySys(K_F5 )
|
||||
#define K_yF6 iup_XkeySys(K_F6 )
|
||||
#define K_yF7 iup_XkeySys(K_F7 )
|
||||
#define K_yF8 iup_XkeySys(K_F8 )
|
||||
#define K_yF9 iup_XkeySys(K_F9 )
|
||||
#define K_yF10 iup_XkeySys(K_F10 )
|
||||
#define K_yF11 iup_XkeySys(K_F11 )
|
||||
#define K_yF12 iup_XkeySys(K_F12 )
|
||||
#define K_yF13 iup_XkeySys(K_F13 )
|
||||
#define K_yF14 iup_XkeySys(K_F14 )
|
||||
#define K_yF15 iup_XkeySys(K_F15 )
|
||||
#define K_yF16 iup_XkeySys(K_F16 )
|
||||
#define K_yF17 iup_XkeySys(K_F17 )
|
||||
#define K_yF18 iup_XkeySys(K_F18 )
|
||||
#define K_yF19 iup_XkeySys(K_F19 )
|
||||
#define K_yF20 iup_XkeySys(K_F20 )
|
||||
#define K_yPrint iup_XkeySys(K_Print )
|
||||
#define K_yMenu iup_XkeySys(K_Menu )
|
||||
|
||||
#define K_sPlus iup_XkeyShift(K_plus )
|
||||
#define K_sComma iup_XkeyShift(K_comma )
|
||||
#define K_sMinus iup_XkeyShift(K_minus )
|
||||
#define K_sPeriod iup_XkeyShift(K_period )
|
||||
#define K_sSlash iup_XkeyShift(K_slash )
|
||||
#define K_sAsterisk iup_XkeyShift(K_asterisk)
|
||||
|
||||
#define K_cA iup_XkeyCtrl(K_A)
|
||||
#define K_cB iup_XkeyCtrl(K_B)
|
||||
#define K_cC iup_XkeyCtrl(K_C)
|
||||
#define K_cD iup_XkeyCtrl(K_D)
|
||||
#define K_cE iup_XkeyCtrl(K_E)
|
||||
#define K_cF iup_XkeyCtrl(K_F)
|
||||
#define K_cG iup_XkeyCtrl(K_G)
|
||||
#define K_cH iup_XkeyCtrl(K_H)
|
||||
#define K_cI iup_XkeyCtrl(K_I)
|
||||
#define K_cJ iup_XkeyCtrl(K_J)
|
||||
#define K_cK iup_XkeyCtrl(K_K)
|
||||
#define K_cL iup_XkeyCtrl(K_L)
|
||||
#define K_cM iup_XkeyCtrl(K_M)
|
||||
#define K_cN iup_XkeyCtrl(K_N)
|
||||
#define K_cO iup_XkeyCtrl(K_O)
|
||||
#define K_cP iup_XkeyCtrl(K_P)
|
||||
#define K_cQ iup_XkeyCtrl(K_Q)
|
||||
#define K_cR iup_XkeyCtrl(K_R)
|
||||
#define K_cS iup_XkeyCtrl(K_S)
|
||||
#define K_cT iup_XkeyCtrl(K_T)
|
||||
#define K_cU iup_XkeyCtrl(K_U)
|
||||
#define K_cV iup_XkeyCtrl(K_V)
|
||||
#define K_cW iup_XkeyCtrl(K_W)
|
||||
#define K_cX iup_XkeyCtrl(K_X)
|
||||
#define K_cY iup_XkeyCtrl(K_Y)
|
||||
#define K_cZ iup_XkeyCtrl(K_Z)
|
||||
#define K_c1 iup_XkeyCtrl(K_1)
|
||||
#define K_c2 iup_XkeyCtrl(K_2)
|
||||
#define K_c3 iup_XkeyCtrl(K_3)
|
||||
#define K_c4 iup_XkeyCtrl(K_4)
|
||||
#define K_c5 iup_XkeyCtrl(K_5)
|
||||
#define K_c6 iup_XkeyCtrl(K_6)
|
||||
#define K_c7 iup_XkeyCtrl(K_7)
|
||||
#define K_c8 iup_XkeyCtrl(K_8)
|
||||
#define K_c9 iup_XkeyCtrl(K_9)
|
||||
#define K_c0 iup_XkeyCtrl(K_0)
|
||||
#define K_cPlus iup_XkeyCtrl(K_plus )
|
||||
#define K_cComma iup_XkeyCtrl(K_comma )
|
||||
#define K_cMinus iup_XkeyCtrl(K_minus )
|
||||
#define K_cPeriod iup_XkeyCtrl(K_period )
|
||||
#define K_cSlash iup_XkeyCtrl(K_slash )
|
||||
#define K_cSemicolon iup_XkeyCtrl(K_semicolon )
|
||||
#define K_cEqual iup_XkeyCtrl(K_equal )
|
||||
#define K_cBracketleft iup_XkeyCtrl(K_bracketleft )
|
||||
#define K_cBracketright iup_XkeyCtrl(K_bracketright)
|
||||
#define K_cBackslash iup_XkeyCtrl(K_backslash )
|
||||
#define K_cAsterisk iup_XkeyCtrl(K_asterisk )
|
||||
|
||||
#define K_mA iup_XkeyAlt(K_A)
|
||||
#define K_mB iup_XkeyAlt(K_B)
|
||||
#define K_mC iup_XkeyAlt(K_C)
|
||||
#define K_mD iup_XkeyAlt(K_D)
|
||||
#define K_mE iup_XkeyAlt(K_E)
|
||||
#define K_mF iup_XkeyAlt(K_F)
|
||||
#define K_mG iup_XkeyAlt(K_G)
|
||||
#define K_mH iup_XkeyAlt(K_H)
|
||||
#define K_mI iup_XkeyAlt(K_I)
|
||||
#define K_mJ iup_XkeyAlt(K_J)
|
||||
#define K_mK iup_XkeyAlt(K_K)
|
||||
#define K_mL iup_XkeyAlt(K_L)
|
||||
#define K_mM iup_XkeyAlt(K_M)
|
||||
#define K_mN iup_XkeyAlt(K_N)
|
||||
#define K_mO iup_XkeyAlt(K_O)
|
||||
#define K_mP iup_XkeyAlt(K_P)
|
||||
#define K_mQ iup_XkeyAlt(K_Q)
|
||||
#define K_mR iup_XkeyAlt(K_R)
|
||||
#define K_mS iup_XkeyAlt(K_S)
|
||||
#define K_mT iup_XkeyAlt(K_T)
|
||||
#define K_mU iup_XkeyAlt(K_U)
|
||||
#define K_mV iup_XkeyAlt(K_V)
|
||||
#define K_mW iup_XkeyAlt(K_W)
|
||||
#define K_mX iup_XkeyAlt(K_X)
|
||||
#define K_mY iup_XkeyAlt(K_Y)
|
||||
#define K_mZ iup_XkeyAlt(K_Z)
|
||||
#define K_m1 iup_XkeyAlt(K_1)
|
||||
#define K_m2 iup_XkeyAlt(K_2)
|
||||
#define K_m3 iup_XkeyAlt(K_3)
|
||||
#define K_m4 iup_XkeyAlt(K_4)
|
||||
#define K_m5 iup_XkeyAlt(K_5)
|
||||
#define K_m6 iup_XkeyAlt(K_6)
|
||||
#define K_m7 iup_XkeyAlt(K_7)
|
||||
#define K_m8 iup_XkeyAlt(K_8)
|
||||
#define K_m9 iup_XkeyAlt(K_9)
|
||||
#define K_m0 iup_XkeyAlt(K_0)
|
||||
#define K_mPlus iup_XkeyAlt(K_plus )
|
||||
#define K_mComma iup_XkeyAlt(K_comma )
|
||||
#define K_mMinus iup_XkeyAlt(K_minus )
|
||||
#define K_mPeriod iup_XkeyAlt(K_period )
|
||||
#define K_mSlash iup_XkeyAlt(K_slash )
|
||||
#define K_mSemicolon iup_XkeyAlt(K_semicolon )
|
||||
#define K_mEqual iup_XkeyAlt(K_equal )
|
||||
#define K_mBracketleft iup_XkeyAlt(K_bracketleft )
|
||||
#define K_mBracketright iup_XkeyAlt(K_bracketright)
|
||||
#define K_mBackslash iup_XkeyAlt(K_backslash )
|
||||
#define K_mAsterisk iup_XkeyAlt(K_asterisk )
|
||||
|
||||
#define K_yA iup_XkeySys(K_A)
|
||||
#define K_yB iup_XkeySys(K_B)
|
||||
#define K_yC iup_XkeySys(K_C)
|
||||
#define K_yD iup_XkeySys(K_D)
|
||||
#define K_yE iup_XkeySys(K_E)
|
||||
#define K_yF iup_XkeySys(K_F)
|
||||
#define K_yG iup_XkeySys(K_G)
|
||||
#define K_yH iup_XkeySys(K_H)
|
||||
#define K_yI iup_XkeySys(K_I)
|
||||
#define K_yJ iup_XkeySys(K_J)
|
||||
#define K_yK iup_XkeySys(K_K)
|
||||
#define K_yL iup_XkeySys(K_L)
|
||||
#define K_yM iup_XkeySys(K_M)
|
||||
#define K_yN iup_XkeySys(K_N)
|
||||
#define K_yO iup_XkeySys(K_O)
|
||||
#define K_yP iup_XkeySys(K_P)
|
||||
#define K_yQ iup_XkeySys(K_Q)
|
||||
#define K_yR iup_XkeySys(K_R)
|
||||
#define K_yS iup_XkeySys(K_S)
|
||||
#define K_yT iup_XkeySys(K_T)
|
||||
#define K_yU iup_XkeySys(K_U)
|
||||
#define K_yV iup_XkeySys(K_V)
|
||||
#define K_yW iup_XkeySys(K_W)
|
||||
#define K_yX iup_XkeySys(K_X)
|
||||
#define K_yY iup_XkeySys(K_Y)
|
||||
#define K_yZ iup_XkeySys(K_Z)
|
||||
#define K_y1 iup_XkeySys(K_1)
|
||||
#define K_y2 iup_XkeySys(K_2)
|
||||
#define K_y3 iup_XkeySys(K_3)
|
||||
#define K_y4 iup_XkeySys(K_4)
|
||||
#define K_y5 iup_XkeySys(K_5)
|
||||
#define K_y6 iup_XkeySys(K_6)
|
||||
#define K_y7 iup_XkeySys(K_7)
|
||||
#define K_y8 iup_XkeySys(K_8)
|
||||
#define K_y9 iup_XkeySys(K_9)
|
||||
#define K_y0 iup_XkeySys(K_0)
|
||||
#define K_yPlus iup_XkeySys(K_plus )
|
||||
#define K_yComma iup_XkeySys(K_comma )
|
||||
#define K_yMinus iup_XkeySys(K_minus )
|
||||
#define K_yPeriod iup_XkeySys(K_period )
|
||||
#define K_ySlash iup_XkeySys(K_slash )
|
||||
#define K_ySemicolon iup_XkeySys(K_semicolon )
|
||||
#define K_yEqual iup_XkeySys(K_equal )
|
||||
#define K_yBracketleft iup_XkeySys(K_bracketleft )
|
||||
#define K_yBracketright iup_XkeySys(K_bracketright)
|
||||
#define K_yBackslash iup_XkeySys(K_backslash )
|
||||
#define K_yAsterisk iup_XkeySys(K_asterisk )
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,54 @@
|
||||
/** \file
|
||||
* \brief IUP Binding for Lua.
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef __IUPLUA_H
|
||||
#define __IUPLUA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_IGNORE_THIS
|
||||
/** @cond DOXYGEN_SHOULD_IGNORE_THIS */
|
||||
#ifndef IUPLUA_API
|
||||
#ifdef IUPLUA_BUILD_LIBRARY
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#define IUPLUA_API EMSCRIPTEN_KEEPALIVE
|
||||
#elif WIN32
|
||||
#define IUPLUA_API __declspec(dllexport)
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 4
|
||||
#define IUPLUA_API __attribute__ ((visibility("default")))
|
||||
#else
|
||||
#define IUPLUA_API
|
||||
#endif
|
||||
#else
|
||||
#define IUPLUA_API
|
||||
#endif /* IUPLUA_BUILD_LIBRARY */
|
||||
#endif /* IUPLUA_API */
|
||||
/** @endcond DOXYGEN_SHOULD_IGNORE_THIS */
|
||||
#endif /* DOXYGEN_SHOULD_IGNORE_THIS */
|
||||
|
||||
|
||||
IUPLUA_API int iuplua_open(lua_State *L);
|
||||
IUPLUA_API int iupkey_open(lua_State *L); /* does nothing, kept for backward compatibility */
|
||||
IUPLUA_API int iuplua_close(lua_State * L);
|
||||
|
||||
/* utilities */
|
||||
IUPLUA_API int iuplua_isihandle(lua_State *L, int pos);
|
||||
IUPLUA_API Ihandle* iuplua_checkihandle(lua_State *L, int pos);
|
||||
IUPLUA_API void iuplua_pushihandle(lua_State *L, Ihandle *n);
|
||||
IUPLUA_API int iuplua_dofile(lua_State *L, const char *filename);
|
||||
IUPLUA_API int iuplua_dostring(lua_State *L, const char *string, const char *chunk_name);
|
||||
IUPLUA_API int iuplua_dobuffer(lua_State *L, const char *buffer, int len, const char *chunk_name);
|
||||
IUPLUA_API void iuplua_show_error_message(const char *pname, const char* msg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,20 @@
|
||||
/** \file
|
||||
* \brief IupMglPlot Binding for Lua.
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef __IUPLUA_MGLPLOT_H
|
||||
#define __IUPLUA_MGLPLOT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int iup_mglplotlua_open (lua_State * L);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,20 @@
|
||||
/** \file
|
||||
* \brief iup_plot Binding for Lua.
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef __IUPLUA_PLOT_H
|
||||
#define __IUPLUA_PLOT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int iup_plotlua_open (lua_State * L);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,20 @@
|
||||
/** \file
|
||||
* \brief IupScintilla Binding for Lua.
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef __IUPLUA_SCINTILLA_H
|
||||
#define __IUPLUA_SCINTILLA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int iup_scintillalua_open (lua_State * L);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,20 @@
|
||||
/** \file
|
||||
* \brief iupcontrols Binding for Lua.
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef __IUPLUACONTROLS_H
|
||||
#define __IUPLUACONTROLS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int iupcontrolslua_open (lua_State * L);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,20 @@
|
||||
/** \file
|
||||
* \brief Binding of new iupfiledlg to Lua.
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef __IUPLUAFILEDLG_H
|
||||
#define __IUPLUAFILEDLG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int iupfiledlglua_open (lua_State * L);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,20 @@
|
||||
/** \file
|
||||
* \brief Binding of iupglcanvas to Lua.
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef __IUPLUAGL_H
|
||||
#define __IUPLUAGL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int iupgllua_open (lua_State * L);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,20 @@
|
||||
/** \file
|
||||
* \brief iupglcontrols Binding for Lua.
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef __IUPLUAGLCONTROLS_H
|
||||
#define __IUPLUAGLCONTROLS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int iupglcontrolslua_open (lua_State * L);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,20 @@
|
||||
/** \file
|
||||
* \brief Bindig of iupim functions to Lua.
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef __IUPLUAIM_H
|
||||
#define __IUPLUAIM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int iupimlua_open(lua_State * L);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,20 @@
|
||||
/** \file
|
||||
* \brief Binding of iupolecontrol to Lua.
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef __IUPLUAOLE_H
|
||||
#define __IUPLUAOLE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int iupolelua_open (lua_State * L);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,25 @@
|
||||
/** \file
|
||||
* \brief IupLuaScripterDlg dialog and Lua binding
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef __IUPLUASCRIPTERDLG_H
|
||||
#define __IUPLUASCRIPTERDLG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void IupLuaScripterDlgOpen(lua_State * L);
|
||||
|
||||
Ihandle* IupLuaScripterDlg(void);
|
||||
|
||||
/* Lua binding */
|
||||
int iupluascripterdlglua_open(lua_State * L);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,20 @@
|
||||
/** \file
|
||||
* \brief Binding of iuptuio to Lua.
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef __IUPLUATUIO_H
|
||||
#define __IUPLUATUIO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int iuptuiolua_open (lua_State * L);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,42 @@
|
||||
/** \file
|
||||
* \brief Binding of iupwebbrowser to Lua.
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef __IUPLUAWEB_H
|
||||
#define __IUPLUAWEB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_IGNORE_THIS
|
||||
/** @cond DOXYGEN_SHOULD_IGNORE_THIS */
|
||||
#ifndef IUPLUAWEB_API
|
||||
#ifdef IUPLUAWEB_BUILD_LIBRARY
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#define IUPLUAWEB_API EMSCRIPTEN_KEEPALIVE
|
||||
#elif WIN32
|
||||
#define IUPLUAWEB_API __declspec(dllexport)
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 4
|
||||
#define IUPLUAWEB_API __attribute__ ((visibility("default")))
|
||||
#else
|
||||
#define IUPLUAWEB_API
|
||||
#endif
|
||||
#else
|
||||
#define IUPLUAWEB_API
|
||||
#endif /* IUPLUAWEB_BUILD_LIBRARY */
|
||||
#endif /* IUPLUAWEB_API */
|
||||
/** @endcond DOXYGEN_SHOULD_IGNORE_THIS */
|
||||
#endif /* DOXYGEN_SHOULD_IGNORE_THIS */
|
||||
|
||||
|
||||
IUPLUAWEB_API int iupweblua_open (lua_State * L);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,45 @@
|
||||
/** \file
|
||||
* \brief Ole control.
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef __IUPOLE_H
|
||||
#define __IUPOLE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_IGNORE_THIS
|
||||
/** @cond DOXYGEN_SHOULD_IGNORE_THIS */
|
||||
#ifndef IUPOLE_API
|
||||
#ifdef IUPOLE_BUILD_LIBRARY
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#define IUPOLE_API EMSCRIPTEN_KEEPALIVE
|
||||
#elif WIN32
|
||||
#define IUPOLE_API __declspec(dllexport)
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 4
|
||||
#define IUPOLE_API __attribute__ ((visibility("default")))
|
||||
#else
|
||||
#define IUPOLE_API
|
||||
#endif
|
||||
#else
|
||||
#define IUPOLE_API
|
||||
#endif /* IUP_BUILD_LIBRARY */
|
||||
#endif /* IUPOLE_API */
|
||||
/** @endcond DOXYGEN_SHOULD_IGNORE_THIS */
|
||||
#endif /* DOXYGEN_SHOULD_IGNORE_THIS */
|
||||
|
||||
|
||||
IUPOLE_API Ihandle *IupOleControl(const char* progid);
|
||||
|
||||
IUPOLE_API int IupOleControlOpen(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,21 @@
|
||||
/** \file
|
||||
* \brief IupTuioClient control
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef __IUPTUIO_H
|
||||
#define __IUPTUIO_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int IupTuioOpen(void);
|
||||
Ihandle* IupTuioClient(int port);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,45 @@
|
||||
/** \file
|
||||
* \brief Web control.
|
||||
*
|
||||
* See Copyright Notice in "iup.h"
|
||||
*/
|
||||
|
||||
#ifndef __IUPWEB_H
|
||||
#define __IUPWEB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_IGNORE_THIS
|
||||
/** @cond DOXYGEN_SHOULD_IGNORE_THIS */
|
||||
#ifndef IUPWEB_API
|
||||
#ifdef IUPWEB_BUILD_LIBRARY
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#define IUPWEB_API EMSCRIPTEN_KEEPALIVE
|
||||
#elif WIN32
|
||||
#define IUPWEB_API __declspec(dllexport)
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 4
|
||||
#define IUPWEB_API __attribute__ ((visibility("default")))
|
||||
#else
|
||||
#define IUPWEB_API
|
||||
#endif
|
||||
#else
|
||||
#define IUPWEB_API
|
||||
#endif /* IUP_BUILD_LIBRARY */
|
||||
#endif /* IUPWEB_API */
|
||||
/** @endcond DOXYGEN_SHOULD_IGNORE_THIS */
|
||||
#endif /* DOXYGEN_SHOULD_IGNORE_THIS */
|
||||
|
||||
|
||||
IUPWEB_API int IupWebBrowserOpen(void);
|
||||
|
||||
IUPWEB_API Ihandle *IupWebBrowser(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user