summaryrefslogtreecommitdiff
path: root/packages/ptc/examples
diff options
context:
space:
mode:
Diffstat (limited to 'packages/ptc/examples')
-rw-r--r--packages/ptc/examples/Makefile2328
-rw-r--r--packages/ptc/examples/Makefile.fpc27
-rw-r--r--packages/ptc/examples/area.pp100
-rw-r--r--packages/ptc/examples/buffer.pp90
-rw-r--r--packages/ptc/examples/clear.pp81
-rw-r--r--packages/ptc/examples/clip.pp109
-rw-r--r--packages/ptc/examples/con_info.pp78
-rw-r--r--packages/ptc/examples/console.pp119
-rw-r--r--packages/ptc/examples/fire.pp265
-rw-r--r--packages/ptc/examples/flower.pp240
-rw-r--r--packages/ptc/examples/hicolor.pp94
-rw-r--r--packages/ptc/examples/image.pp106
-rw-r--r--packages/ptc/examples/image.tgabin0 -> 192044 bytes
-rw-r--r--packages/ptc/examples/keyboard.pp116
-rw-r--r--packages/ptc/examples/keybrd2.pp120
-rw-r--r--packages/ptc/examples/land.pp402
-rw-r--r--packages/ptc/examples/lights.pp290
-rw-r--r--packages/ptc/examples/modes.pp100
-rw-r--r--packages/ptc/examples/mojo.pp815
-rw-r--r--packages/ptc/examples/mojo.rawbin0 -> 64000 bytes
-rw-r--r--packages/ptc/examples/palette.pp102
-rw-r--r--packages/ptc/examples/pixel.pp84
-rw-r--r--packages/ptc/examples/random.pp92
-rw-r--r--packages/ptc/examples/save.pp290
-rw-r--r--packages/ptc/examples/stretch.pp164
-rw-r--r--packages/ptc/examples/stretch.tgabin0 -> 134444 bytes
-rw-r--r--packages/ptc/examples/texwarp.pp396
-rw-r--r--packages/ptc/examples/timer.pp116
-rw-r--r--packages/ptc/examples/tunnel.pp198
-rw-r--r--packages/ptc/examples/tunnel3d.pp612
-rw-r--r--packages/ptc/examples/tunnel3d.raw217
31 files changed, 7751 insertions, 0 deletions
diff --git a/packages/ptc/examples/Makefile b/packages/ptc/examples/Makefile
new file mode 100644
index 0000000000..7fcb744bb4
--- /dev/null
+++ b/packages/ptc/examples/Makefile
@@ -0,0 +1,2328 @@
+#
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2008/01/26]
+#
+default: all
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded
+BSDs = freebsd netbsd openbsd darwin
+UNIXs = linux $(BSDs) solaris qnx
+LIMIT83fs = go32v2 os2 emx watcom
+OSNeedsComspecToRunBatch = go32v2 watcom
+FORCE:
+.PHONY: FORCE
+override PATH:=$(patsubst %/,%,$(subst \,/,$(PATH)))
+ifneq ($(findstring darwin,$(OSTYPE)),)
+inUnix=1 #darwin
+SEARCHPATH:=$(filter-out .,$(subst :, ,$(PATH)))
+else
+ifeq ($(findstring ;,$(PATH)),)
+inUnix=1
+SEARCHPATH:=$(filter-out .,$(subst :, ,$(PATH)))
+else
+SEARCHPATH:=$(subst ;, ,$(PATH))
+endif
+endif
+SEARCHPATH+=$(patsubst %/,%,$(subst \,/,$(dir $(MAKE))))
+PWD:=$(strip $(wildcard $(addsuffix /pwd.exe,$(SEARCHPATH))))
+ifeq ($(PWD),)
+PWD:=$(strip $(wildcard $(addsuffix /pwd,$(SEARCHPATH))))
+ifeq ($(PWD),)
+$(error You need the GNU utils package to use this Makefile)
+else
+PWD:=$(firstword $(PWD))
+SRCEXEEXT=
+endif
+else
+PWD:=$(firstword $(PWD))
+SRCEXEEXT=.exe
+endif
+ifndef inUnix
+ifeq ($(OS),Windows_NT)
+inWinNT=1
+else
+ifdef OS2_SHELL
+inOS2=1
+endif
+endif
+else
+ifneq ($(findstring cygdrive,$(PATH)),)
+inCygWin=1
+endif
+endif
+ifdef inUnix
+SRCBATCHEXT=.sh
+else
+ifdef inOS2
+SRCBATCHEXT=.cmd
+else
+SRCBATCHEXT=.bat
+endif
+endif
+ifdef COMSPEC
+ifneq ($(findstring $(OS_SOURCE),$(OSNeedsComspecToRunBatch)),)
+RUNBATCH=$(COMSPEC) /C
+endif
+endif
+ifdef inUnix
+PATHSEP=/
+else
+PATHSEP:=$(subst /,\,/)
+ifdef inCygWin
+PATHSEP=/
+endif
+endif
+ifdef PWD
+BASEDIR:=$(subst \,/,$(shell $(PWD)))
+ifdef inCygWin
+ifneq ($(findstring /cygdrive/,$(BASEDIR)),)
+BASENODIR:=$(patsubst /cygdrive%,%,$(BASEDIR))
+BASEDRIVE:=$(firstword $(subst /, ,$(BASENODIR)))
+BASEDIR:=$(subst /cygdrive/$(BASEDRIVE)/,$(BASEDRIVE):/,$(BASEDIR))
+endif
+endif
+else
+BASEDIR=.
+endif
+ifdef inOS2
+ifndef ECHO
+ECHO:=$(strip $(wildcard $(addsuffix /gecho$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO:=$(strip $(wildcard $(addsuffix /echo$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO=echo
+else
+ECHO:=$(firstword $(ECHO))
+endif
+else
+ECHO:=$(firstword $(ECHO))
+endif
+endif
+export ECHO
+endif
+override DEFAULT_FPCDIR=../../..
+ifndef FPC
+ifdef PP
+FPC=$(PP)
+endif
+endif
+ifndef FPC
+FPCPROG:=$(strip $(wildcard $(addsuffix /fpc$(SRCEXEEXT),$(SEARCHPATH))))
+ifneq ($(FPCPROG),)
+FPCPROG:=$(firstword $(FPCPROG))
+ifneq ($(CPU_TARGET),)
+FPC:=$(shell $(FPCPROG) -P$(CPU_TARGET) -PB)
+else
+FPC:=$(shell $(FPCPROG) -PB)
+endif
+ifneq ($(findstring Error,$(FPC)),)
+override FPC=$(firstword $(strip $(wildcard $(addsuffix /ppc386$(SRCEXEEXT),$(SEARCHPATH)))))
+endif
+else
+override FPC=$(firstword $(strip $(wildcard $(addsuffix /ppc386$(SRCEXEEXT),$(SEARCHPATH)))))
+endif
+endif
+override FPC:=$(subst $(SRCEXEEXT),,$(FPC))
+override FPC:=$(subst \,/,$(FPC))$(SRCEXEEXT)
+FOUNDFPC:=$(strip $(wildcard $(FPC)))
+ifeq ($(FOUNDFPC),)
+FOUNDFPC=$(strip $(wildcard $(addsuffix /$(FPC),$(SEARCHPATH))))
+ifeq ($(FOUNDFPC),)
+$(error Compiler $(FPC) not found)
+endif
+endif
+ifndef FPC_COMPILERINFO
+FPC_COMPILERINFO:=$(shell $(FPC) -iVSPTPSOTO)
+endif
+ifndef FPC_VERSION
+FPC_VERSION:=$(word 1,$(FPC_COMPILERINFO))
+endif
+export FPC FPC_VERSION FPC_COMPILERINFO
+unexport CHECKDEPEND ALLDEPENDENCIES
+ifndef CPU_TARGET
+ifdef CPU_TARGET_DEFAULT
+CPU_TARGET=$(CPU_TARGET_DEFAULT)
+endif
+endif
+ifndef OS_TARGET
+ifdef OS_TARGET_DEFAULT
+OS_TARGET=$(OS_TARGET_DEFAULT)
+endif
+endif
+ifneq ($(words $(FPC_COMPILERINFO)),5)
+FPC_COMPILERINFO+=$(shell $(FPC) -iSP)
+FPC_COMPILERINFO+=$(shell $(FPC) -iTP)
+FPC_COMPILERINFO+=$(shell $(FPC) -iSO)
+FPC_COMPILERINFO+=$(shell $(FPC) -iTO)
+endif
+ifndef CPU_SOURCE
+CPU_SOURCE:=$(word 2,$(FPC_COMPILERINFO))
+endif
+ifndef CPU_TARGET
+CPU_TARGET:=$(word 3,$(FPC_COMPILERINFO))
+endif
+ifndef OS_SOURCE
+OS_SOURCE:=$(word 4,$(FPC_COMPILERINFO))
+endif
+ifndef OS_TARGET
+OS_TARGET:=$(word 5,$(FPC_COMPILERINFO))
+endif
+FULL_TARGET=$(CPU_TARGET)-$(OS_TARGET)
+FULL_SOURCE=$(CPU_SOURCE)-$(OS_SOURCE)
+ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
+TARGETSUFFIX=$(OS_TARGET)
+SOURCESUFFIX=$(OS_SOURCE)
+else
+TARGETSUFFIX=$(FULL_TARGET)
+SOURCESUFFIX=$(FULL_SOURCE)
+endif
+ifneq ($(FULL_TARGET),$(FULL_SOURCE))
+CROSSCOMPILE=1
+endif
+ifeq ($(findstring makefile,$(MAKECMDGOALS)),)
+ifeq ($(findstring $(FULL_TARGET),$(MAKEFILETARGETS)),)
+$(error The Makefile doesn't support target $(FULL_TARGET), please run fpcmake first)
+endif
+endif
+ifneq ($(findstring $(OS_TARGET),$(BSDs)),)
+BSDhier=1
+endif
+ifeq ($(OS_TARGET),linux)
+linuxHier=1
+endif
+export OS_TARGET OS_SOURCE CPU_TARGET CPU_SOURCE FULL_TARGET FULL_SOURCE TARGETSUFFIX SOURCESUFFIX CROSSCOMPILE
+ifdef FPCDIR
+override FPCDIR:=$(subst \,/,$(FPCDIR))
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR=wrong
+endif
+else
+override FPCDIR=wrong
+endif
+ifdef DEFAULT_FPCDIR
+ifeq ($(FPCDIR),wrong)
+override FPCDIR:=$(subst \,/,$(DEFAULT_FPCDIR))
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR=wrong
+endif
+endif
+endif
+ifeq ($(FPCDIR),wrong)
+ifdef inUnix
+override FPCDIR=/usr/local/lib/fpc/$(FPC_VERSION)
+ifeq ($(wildcard $(FPCDIR)/units),)
+override FPCDIR=/usr/lib/fpc/$(FPC_VERSION)
+endif
+else
+override FPCDIR:=$(subst /$(FPC),,$(firstword $(strip $(wildcard $(addsuffix /$(FPC),$(SEARCHPATH))))))
+override FPCDIR:=$(FPCDIR)/..
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR:=$(FPCDIR)/..
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR:=$(BASEDIR)
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR=c:/pp
+endif
+endif
+endif
+endif
+endif
+ifndef CROSSBINDIR
+CROSSBINDIR:=$(wildcard $(FPCDIR)/bin/$(TARGETSUFFIX))
+endif
+ifndef BINUTILSPREFIX
+ifndef CROSSBINDIR
+ifdef CROSSCOMPILE
+BINUTILSPREFIX=$(CPU_TARGET)-$(OS_TARGET)-
+endif
+endif
+endif
+UNITSDIR:=$(wildcard $(FPCDIR)/units/$(TARGETSUFFIX))
+ifeq ($(UNITSDIR),)
+UNITSDIR:=$(wildcard $(FPCDIR)/units/$(OS_TARGET))
+endif
+PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages $(FPCDIR)/packages/base $(FPCDIR)/packages/extra)
+override PACKAGE_NAME=ptc-examples
+override PACKAGE_VERSION=0.99.5
+ifeq ($(FULL_TARGET),i386-linux)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+override TARGET_PROGRAMS+=area buffer clear clip con_info console fire flower hicolor image keyboard keybrd2 land lights modes mojo palette pixel random save stretch texwarp timer tunnel3d tunnel
+endif
+ifeq ($(FULL_TARGET),i386-linux)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+override COMPILER_UNITDIR+=../$(UNITTARGETDIRPREFIX)
+endif
+ifdef REQUIRE_UNITSDIR
+override UNITSDIR+=$(REQUIRE_UNITSDIR)
+endif
+ifdef REQUIRE_PACKAGESDIR
+override PACKAGESDIR+=$(REQUIRE_PACKAGESDIR)
+endif
+ifdef ZIPINSTALL
+ifneq ($(findstring $(OS_TARGET),$(UNIXs)),)
+UNIXHier=1
+endif
+else
+ifneq ($(findstring $(OS_SOURCE),$(UNIXs)),)
+UNIXHier=1
+endif
+endif
+ifndef INSTALL_PREFIX
+ifdef PREFIX
+INSTALL_PREFIX=$(PREFIX)
+endif
+endif
+ifndef INSTALL_PREFIX
+ifdef UNIXHier
+INSTALL_PREFIX=/usr/local
+else
+ifdef INSTALL_FPCPACKAGE
+INSTALL_BASEDIR:=/pp
+else
+INSTALL_BASEDIR:=/$(PACKAGE_NAME)
+endif
+endif
+endif
+export INSTALL_PREFIX
+ifdef INSTALL_FPCSUBDIR
+export INSTALL_FPCSUBDIR
+endif
+ifndef DIST_DESTDIR
+DIST_DESTDIR:=$(BASEDIR)
+endif
+export DIST_DESTDIR
+ifndef COMPILER_UNITTARGETDIR
+ifdef PACKAGEDIR_MAIN
+COMPILER_UNITTARGETDIR=$(PACKAGEDIR_MAIN)/units/$(TARGETSUFFIX)
+else
+COMPILER_UNITTARGETDIR=units/$(TARGETSUFFIX)
+endif
+endif
+ifndef COMPILER_TARGETDIR
+COMPILER_TARGETDIR=.
+endif
+ifndef INSTALL_BASEDIR
+ifdef UNIXHier
+ifdef INSTALL_FPCPACKAGE
+INSTALL_BASEDIR:=$(INSTALL_PREFIX)/lib/fpc/$(FPC_VERSION)
+else
+INSTALL_BASEDIR:=$(INSTALL_PREFIX)/lib/$(PACKAGE_NAME)
+endif
+else
+INSTALL_BASEDIR:=$(INSTALL_PREFIX)
+endif
+endif
+ifndef INSTALL_BINDIR
+ifdef UNIXHier
+INSTALL_BINDIR:=$(INSTALL_PREFIX)/bin
+else
+INSTALL_BINDIR:=$(INSTALL_BASEDIR)/bin
+ifdef INSTALL_FPCPACKAGE
+ifdef CROSSCOMPILE
+ifdef CROSSINSTALL
+INSTALL_BINDIR:=$(INSTALL_BINDIR)/$(SOURCESUFFIX)
+else
+INSTALL_BINDIR:=$(INSTALL_BINDIR)/$(TARGETSUFFIX)
+endif
+else
+INSTALL_BINDIR:=$(INSTALL_BINDIR)/$(TARGETSUFFIX)
+endif
+endif
+endif
+endif
+ifndef INSTALL_UNITDIR
+INSTALL_UNITDIR:=$(INSTALL_BASEDIR)/units/$(TARGETSUFFIX)
+ifdef INSTALL_FPCPACKAGE
+ifdef PACKAGE_NAME
+INSTALL_UNITDIR:=$(INSTALL_UNITDIR)/$(PACKAGE_NAME)
+endif
+endif
+endif
+ifndef INSTALL_LIBDIR
+ifdef UNIXHier
+INSTALL_LIBDIR:=$(INSTALL_PREFIX)/lib
+else
+INSTALL_LIBDIR:=$(INSTALL_UNITDIR)
+endif
+endif
+ifndef INSTALL_SOURCEDIR
+ifdef UNIXHier
+ifdef BSDhier
+SRCPREFIXDIR=share/src
+else
+ifdef linuxHier
+SRCPREFIXDIR=share/src
+else
+SRCPREFIXDIR=src
+endif
+endif
+ifdef INSTALL_FPCPACKAGE
+ifdef INSTALL_FPCSUBDIR
+INSTALL_SOURCEDIR:=$(INSTALL_PREFIX)/$(SRCPREFIXDIR)/fpc-$(FPC_VERSION)/$(INSTALL_FPCSUBDIR)/$(PACKAGE_NAME)
+else
+INSTALL_SOURCEDIR:=$(INSTALL_PREFIX)/$(SRCPREFIXDIR)/fpc-$(FPC_VERSION)/$(PACKAGE_NAME)
+endif
+else
+INSTALL_SOURCEDIR:=$(INSTALL_PREFIX)/$(SRCPREFIXDIR)/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+endif
+else
+ifdef INSTALL_FPCPACKAGE
+ifdef INSTALL_FPCSUBDIR
+INSTALL_SOURCEDIR:=$(INSTALL_BASEDIR)/source/$(INSTALL_FPCSUBDIR)/$(PACKAGE_NAME)
+else
+INSTALL_SOURCEDIR:=$(INSTALL_BASEDIR)/source/$(PACKAGE_NAME)
+endif
+else
+INSTALL_SOURCEDIR:=$(INSTALL_BASEDIR)/source
+endif
+endif
+endif
+ifndef INSTALL_DOCDIR
+ifdef UNIXHier
+ifdef BSDhier
+DOCPREFIXDIR=share/doc
+else
+ifdef linuxHier
+DOCPREFIXDIR=share/doc
+else
+DOCPREFIXDIR=doc
+endif
+endif
+ifdef INSTALL_FPCPACKAGE
+INSTALL_DOCDIR:=$(INSTALL_PREFIX)/$(DOCPREFIXDIR)/fpc-$(FPC_VERSION)/$(PACKAGE_NAME)
+else
+INSTALL_DOCDIR:=$(INSTALL_PREFIX)/$(DOCPREFIXDIR)/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+endif
+else
+ifdef INSTALL_FPCPACKAGE
+INSTALL_DOCDIR:=$(INSTALL_BASEDIR)/doc/$(PACKAGE_NAME)
+else
+INSTALL_DOCDIR:=$(INSTALL_BASEDIR)/doc
+endif
+endif
+endif
+ifndef INSTALL_EXAMPLEDIR
+ifdef UNIXHier
+ifdef INSTALL_FPCPACKAGE
+ifdef BSDhier
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/share/examples/fpc-$(FPC_VERSION)/$(PACKAGE_NAME)
+else
+ifdef linuxHier
+INSTALL_EXAMPLEDIR:=$(INSTALL_DOCDIR)/examples
+else
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/doc/fpc-$(FPC_VERSION)/examples/$(PACKAGE_NAME)
+endif
+endif
+else
+ifdef BSDhier
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/share/examples/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+else
+ifdef linuxHier
+INSTALL_EXAMPLEDIR:=$(INSTALL_DOCDIR)/examples/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+else
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/doc/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+endif
+endif
+endif
+else
+ifdef INSTALL_FPCPACKAGE
+INSTALL_EXAMPLEDIR:=$(INSTALL_BASEDIR)/examples/$(PACKAGE_NAME)
+else
+INSTALL_EXAMPLEDIR:=$(INSTALL_BASEDIR)/examples
+endif
+endif
+endif
+ifndef INSTALL_DATADIR
+INSTALL_DATADIR=$(INSTALL_BASEDIR)
+endif
+ifndef INSTALL_SHAREDDIR
+INSTALL_SHAREDDIR=$(INSTALL_PREFIX)/lib
+endif
+ifdef CROSSCOMPILE
+ifndef CROSSBINDIR
+CROSSBINDIR:=$(wildcard $(CROSSTARGETDIR)/bin/$(SOURCESUFFIX))
+ifeq ($(CROSSBINDIR),)
+CROSSBINDIR:=$(wildcard $(INSTALL_BASEDIR)/cross/$(TARGETSUFFIX)/bin/$(FULL_SOURCE))
+endif
+endif
+else
+CROSSBINDIR=
+endif
+ifeq ($(OS_SOURCE),linux)
+ifndef GCCLIBDIR
+ifeq ($(CPU_TARGET),i386)
+ifneq ($(findstring x86_64,$(shell uname -a)),)
+ifeq ($(BINUTILSPREFIX),)
+GCCLIBDIR:=$(shell dirname `gcc -m32 -print-libgcc-file-name`)
+endif
+endif
+endif
+ifeq ($(CPU_TARGET),powerpc64)
+ifeq ($(BINUTILSPREFIX),)
+GCCLIBDIR:=$(shell dirname `gcc -m64 -print-libgcc-file-name`)
+endif
+endif
+endif
+ifndef GCCLIBDIR
+CROSSGCC=$(strip $(wildcard $(addsuffix /$(BINUTILSPREFIX)gcc$(SRCEXEEXT),$(SEARCHPATH))))
+ifneq ($(CROSSGCC),)
+GCCLIBDIR:=$(shell dirname `$(CROSSGCC) -print-libgcc-file-name`)
+endif
+endif
+ifndef OTHERLIBDIR
+OTHERLIBDIR:=$(shell grep -v "^\#" /etc/ld.so.conf | awk '{ ORS=" "; print $1 }')
+endif
+endif
+ifdef inUnix
+ifeq ($(OS_SOURCE),netbsd)
+OTHERLIBDIR+=/usr/pkg/lib
+endif
+export GCCLIBDIR OTHERLIB
+endif
+BATCHEXT=.bat
+LOADEREXT=.as
+EXEEXT=.exe
+PPLEXT=.ppl
+PPUEXT=.ppu
+OEXT=.o
+ASMEXT=.s
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.so
+SHAREDLIBPREFIX=libfp
+STATICLIBPREFIX=libp
+IMPORTLIBPREFIX=libimp
+RSTEXT=.rst
+ifeq ($(findstring 1.0.,$(FPC_VERSION)),)
+ifeq ($(OS_TARGET),go32v1)
+STATICLIBPREFIX=
+SHORTSUFFIX=v1
+endif
+ifeq ($(OS_TARGET),go32v2)
+STATICLIBPREFIX=
+SHORTSUFFIX=dos
+endif
+ifeq ($(OS_TARGET),watcom)
+STATICLIBPREFIX=
+OEXT=.obj
+ASMEXT=.asm
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=wat
+endif
+ifeq ($(OS_TARGET),linux)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=lnx
+endif
+ifeq ($(OS_TARGET),freebsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=fbs
+endif
+ifeq ($(OS_TARGET),netbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=nbs
+endif
+ifeq ($(OS_TARGET),openbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=obs
+endif
+ifeq ($(OS_TARGET),win32)
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=w32
+endif
+ifeq ($(OS_TARGET),os2)
+BATCHEXT=.cmd
+AOUTEXT=.out
+STATICLIBPREFIX=
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=os2
+ECHO=echo
+endif
+ifeq ($(OS_TARGET),emx)
+BATCHEXT=.cmd
+AOUTEXT=.out
+STATICLIBPREFIX=
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=emx
+ECHO=echo
+endif
+ifeq ($(OS_TARGET),amiga)
+EXEEXT=
+SHAREDLIBEXT=.library
+SHORTSUFFIX=amg
+endif
+ifeq ($(OS_TARGET),morphos)
+EXEEXT=
+SHAREDLIBEXT=.library
+SHORTSUFFIX=mos
+endif
+ifeq ($(OS_TARGET),atari)
+EXEEXT=.ttp
+SHORTSUFFIX=ata
+endif
+ifeq ($(OS_TARGET),beos)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=be
+endif
+ifeq ($(OS_TARGET),solaris)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=sun
+endif
+ifeq ($(OS_TARGET),qnx)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=qnx
+endif
+ifeq ($(OS_TARGET),netware)
+EXEEXT=.nlm
+STATICLIBPREFIX=
+SHORTSUFFIX=nw
+endif
+ifeq ($(OS_TARGET),netwlibc)
+EXEEXT=.nlm
+STATICLIBPREFIX=
+SHORTSUFFIX=nwl
+endif
+ifeq ($(OS_TARGET),macos)
+BATCHEXT=
+EXEEXT=
+DEBUGSYMEXT=.xcoff
+SHORTSUFFIX=mac
+endif
+ifeq ($(OS_TARGET),darwin)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=dwn
+endif
+ifeq ($(OS_TARGET),gba)
+EXEEXT=.gba
+SHAREDLIBEXT=.so
+SHORTSUFFIX=gba
+endif
+ifeq ($(OS_TARGET),symbian)
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=symbian
+endif
+else
+ifeq ($(OS_TARGET),go32v1)
+PPUEXT=.pp1
+OEXT=.o1
+ASMEXT=.s1
+SMARTEXT=.sl1
+STATICLIBEXT=.a1
+SHAREDLIBEXT=.so1
+STATICLIBPREFIX=
+SHORTSUFFIX=v1
+endif
+ifeq ($(OS_TARGET),go32v2)
+STATICLIBPREFIX=
+SHORTSUFFIX=dos
+endif
+ifeq ($(OS_TARGET),watcom)
+STATICLIBPREFIX=
+SHORTSUFFIX=wat
+endif
+ifeq ($(OS_TARGET),linux)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=lnx
+endif
+ifeq ($(OS_TARGET),freebsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=fbs
+endif
+ifeq ($(OS_TARGET),netbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=nbs
+endif
+ifeq ($(OS_TARGET),openbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=obs
+endif
+ifeq ($(OS_TARGET),win32)
+PPUEXT=.ppw
+OEXT=.ow
+ASMEXT=.sw
+SMARTEXT=.slw
+STATICLIBEXT=.aw
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=w32
+endif
+ifeq ($(OS_TARGET),os2)
+BATCHEXT=.cmd
+PPUEXT=.ppo
+ASMEXT=.so2
+OEXT=.oo2
+AOUTEXT=.out
+SMARTEXT=.sl2
+STATICLIBPREFIX=
+STATICLIBEXT=.ao2
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=os2
+ECHO=echo
+endif
+ifeq ($(OS_TARGET),amiga)
+EXEEXT=
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.library
+SHORTSUFFIX=amg
+endif
+ifeq ($(OS_TARGET),atari)
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=.ttp
+SHORTSUFFIX=ata
+endif
+ifeq ($(OS_TARGET),beos)
+BATCHEXT=.sh
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=
+SHORTSUFFIX=be
+endif
+ifeq ($(OS_TARGET),solaris)
+BATCHEXT=.sh
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=
+SHORTSUFFIX=sun
+endif
+ifeq ($(OS_TARGET),qnx)
+BATCHEXT=.sh
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=
+SHORTSUFFIX=qnx
+endif
+ifeq ($(OS_TARGET),netware)
+STATICLIBPREFIX=
+PPUEXT=.ppu
+OEXT=.o
+ASMEXT=.s
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.nlm
+EXEEXT=.nlm
+SHORTSUFFIX=nw
+endif
+ifeq ($(OS_TARGET),netwlibc)
+STATICLIBPREFIX=
+PPUEXT=.ppu
+OEXT=.o
+ASMEXT=.s
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.nlm
+EXEEXT=.nlm
+SHORTSUFFIX=nwl
+endif
+ifeq ($(OS_TARGET),macos)
+BATCHEXT=
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=
+DEBUGSYMEXT=.xcoff
+SHORTSUFFIX=mac
+endif
+endif
+ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
+FPCMADE=fpcmade.$(SHORTSUFFIX)
+ZIPSUFFIX=$(SHORTSUFFIX)
+ZIPCROSSPREFIX=
+ZIPSOURCESUFFIX=src
+ZIPEXAMPLESUFFIX=exm
+else
+FPCMADE=fpcmade.$(TARGETSUFFIX)
+ZIPSOURCESUFFIX=.source
+ZIPEXAMPLESUFFIX=.examples
+ifdef CROSSCOMPILE
+ZIPSUFFIX=.$(SOURCESUFFIX)
+ZIPCROSSPREFIX=$(TARGETSUFFIX)-
+else
+ZIPSUFFIX=.$(TARGETSUFFIX)
+ZIPCROSSPREFIX=
+endif
+endif
+ifndef ECHO
+ECHO:=$(strip $(wildcard $(addsuffix /gecho$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO:=$(strip $(wildcard $(addsuffix /echo$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO= __missing_command_ECHO
+else
+ECHO:=$(firstword $(ECHO))
+endif
+else
+ECHO:=$(firstword $(ECHO))
+endif
+endif
+export ECHO
+ifndef DATE
+DATE:=$(strip $(wildcard $(addsuffix /gdate$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(DATE),)
+DATE:=$(strip $(wildcard $(addsuffix /date$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(DATE),)
+DATE= __missing_command_DATE
+else
+DATE:=$(firstword $(DATE))
+endif
+else
+DATE:=$(firstword $(DATE))
+endif
+endif
+export DATE
+ifndef GINSTALL
+GINSTALL:=$(strip $(wildcard $(addsuffix /ginstall$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(GINSTALL),)
+GINSTALL:=$(strip $(wildcard $(addsuffix /install$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(GINSTALL),)
+GINSTALL= __missing_command_GINSTALL
+else
+GINSTALL:=$(firstword $(GINSTALL))
+endif
+else
+GINSTALL:=$(firstword $(GINSTALL))
+endif
+endif
+export GINSTALL
+ifndef CPPROG
+CPPROG:=$(strip $(wildcard $(addsuffix /cp$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(CPPROG),)
+CPPROG= __missing_command_CPPROG
+else
+CPPROG:=$(firstword $(CPPROG))
+endif
+endif
+export CPPROG
+ifndef RMPROG
+RMPROG:=$(strip $(wildcard $(addsuffix /rm$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(RMPROG),)
+RMPROG= __missing_command_RMPROG
+else
+RMPROG:=$(firstword $(RMPROG))
+endif
+endif
+export RMPROG
+ifndef MVPROG
+MVPROG:=$(strip $(wildcard $(addsuffix /mv$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MVPROG),)
+MVPROG= __missing_command_MVPROG
+else
+MVPROG:=$(firstword $(MVPROG))
+endif
+endif
+export MVPROG
+ifndef MKDIRPROG
+MKDIRPROG:=$(strip $(wildcard $(addsuffix /gmkdir$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MKDIRPROG),)
+MKDIRPROG:=$(strip $(wildcard $(addsuffix /mkdir$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MKDIRPROG),)
+MKDIRPROG= __missing_command_MKDIRPROG
+else
+MKDIRPROG:=$(firstword $(MKDIRPROG))
+endif
+else
+MKDIRPROG:=$(firstword $(MKDIRPROG))
+endif
+endif
+export MKDIRPROG
+ifndef ECHOREDIR
+ifndef inUnix
+ECHOREDIR=echo
+else
+ECHOREDIR=$(ECHO)
+endif
+endif
+ifndef COPY
+COPY:=$(CPPROG) -fp
+endif
+ifndef COPYTREE
+COPYTREE:=$(CPPROG) -Rfp
+endif
+ifndef MKDIRTREE
+MKDIRTREE:=$(MKDIRPROG) -p
+endif
+ifndef MOVE
+MOVE:=$(MVPROG) -f
+endif
+ifndef DEL
+DEL:=$(RMPROG) -f
+endif
+ifndef DELTREE
+DELTREE:=$(RMPROG) -rf
+endif
+ifndef INSTALL
+ifdef inUnix
+INSTALL:=$(GINSTALL) -c -m 644
+else
+INSTALL:=$(COPY)
+endif
+endif
+ifndef INSTALLEXE
+ifdef inUnix
+INSTALLEXE:=$(GINSTALL) -c -m 755
+else
+INSTALLEXE:=$(COPY)
+endif
+endif
+ifndef MKDIR
+MKDIR:=$(GINSTALL) -m 755 -d
+endif
+export ECHOREDIR COPY COPYTREE MOVE DEL DELTREE INSTALL INSTALLEXE MKDIR
+ifndef PPUMOVE
+PPUMOVE:=$(strip $(wildcard $(addsuffix /ppumove$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(PPUMOVE),)
+PPUMOVE= __missing_command_PPUMOVE
+else
+PPUMOVE:=$(firstword $(PPUMOVE))
+endif
+endif
+export PPUMOVE
+ifndef FPCMAKE
+FPCMAKE:=$(strip $(wildcard $(addsuffix /fpcmake$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(FPCMAKE),)
+FPCMAKE= __missing_command_FPCMAKE
+else
+FPCMAKE:=$(firstword $(FPCMAKE))
+endif
+endif
+export FPCMAKE
+ifndef ZIPPROG
+ZIPPROG:=$(strip $(wildcard $(addsuffix /zip$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ZIPPROG),)
+ZIPPROG= __missing_command_ZIPPROG
+else
+ZIPPROG:=$(firstword $(ZIPPROG))
+endif
+endif
+export ZIPPROG
+ifndef TARPROG
+TARPROG:=$(strip $(wildcard $(addsuffix /gtar$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(TARPROG),)
+TARPROG:=$(strip $(wildcard $(addsuffix /tar$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(TARPROG),)
+TARPROG= __missing_command_TARPROG
+else
+TARPROG:=$(firstword $(TARPROG))
+endif
+else
+TARPROG:=$(firstword $(TARPROG))
+endif
+endif
+export TARPROG
+ASNAME=$(BINUTILSPREFIX)as
+LDNAME=$(BINUTILSPREFIX)ld
+ARNAME=$(BINUTILSPREFIX)ar
+RCNAME=$(BINUTILSPREFIX)rc
+ifneq ($(findstring 1.0.,$(FPC_VERSION)),)
+ifeq ($(OS_TARGET),win32)
+ifeq ($(CROSSBINDIR),)
+ASNAME=asw
+LDNAME=ldw
+ARNAME=arw
+endif
+endif
+endif
+ifndef ASPROG
+ifdef CROSSBINDIR
+ASPROG=$(CROSSBINDIR)/$(ASNAME)$(SRCEXEEXT)
+else
+ASPROG=$(ASNAME)
+endif
+endif
+ifndef LDPROG
+ifdef CROSSBINDIR
+LDPROG=$(CROSSBINDIR)/$(LDNAME)$(SRCEXEEXT)
+else
+LDPROG=$(LDNAME)
+endif
+endif
+ifndef RCPROG
+ifdef CROSSBINDIR
+RCPROG=$(CROSSBINDIR)/$(RCNAME)$(SRCEXEEXT)
+else
+RCPROG=$(RCNAME)
+endif
+endif
+ifndef ARPROG
+ifdef CROSSBINDIR
+ARPROG=$(CROSSBINDIR)/$(ARNAME)$(SRCEXEEXT)
+else
+ARPROG=$(ARNAME)
+endif
+endif
+AS=$(ASPROG)
+LD=$(LDPROG)
+RC=$(RCPROG)
+AR=$(ARPROG)
+PPAS=ppas$(SRCBATCHEXT)
+ifdef inUnix
+LDCONFIG=ldconfig
+else
+LDCONFIG=
+endif
+ifdef DATE
+DATESTR:=$(shell $(DATE) +%Y%m%d)
+else
+DATESTR=
+endif
+ifndef UPXPROG
+ifeq ($(OS_TARGET),go32v2)
+UPXPROG:=1
+endif
+ifeq ($(OS_TARGET),win32)
+UPXPROG:=1
+endif
+ifdef UPXPROG
+UPXPROG:=$(strip $(wildcard $(addsuffix /upx$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(UPXPROG),)
+UPXPROG=
+else
+UPXPROG:=$(firstword $(UPXPROG))
+endif
+else
+UPXPROG=
+endif
+endif
+export UPXPROG
+ZIPOPT=-9
+ZIPEXT=.zip
+ifeq ($(USETAR),bz2)
+TAROPT=vj
+TAREXT=.tar.bz2
+else
+TAROPT=vz
+TAREXT=.tar.gz
+endif
+override REQUIRE_PACKAGES=rtl hermes ptc
+ifeq ($(FULL_TARGET),i386-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_X11=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_X11=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_X11=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_X11=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_X11=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_X11=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_X11=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_X11=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_X11=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_X11=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_HERMES=1
+REQUIRE_PACKAGES_PTC=1
+endif
+ifdef REQUIRE_PACKAGES_RTL
+PACKAGEDIR_RTL:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /rtl/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_RTL),)
+ifneq ($(wildcard $(PACKAGEDIR_RTL)/units/$(TARGETSUFFIX)),)
+UNITDIR_RTL=$(PACKAGEDIR_RTL)/units/$(TARGETSUFFIX)
+else
+UNITDIR_RTL=$(PACKAGEDIR_RTL)
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_RTL)/$(FPCMADE):
+ $(MAKE) -C $(PACKAGEDIR_RTL) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_RTL)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_RTL=
+UNITDIR_RTL:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /rtl/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_RTL),)
+UNITDIR_RTL:=$(firstword $(UNITDIR_RTL))
+else
+UNITDIR_RTL=
+endif
+endif
+ifdef UNITDIR_RTL
+override COMPILER_UNITDIR+=$(UNITDIR_RTL)
+endif
+endif
+ifdef REQUIRE_PACKAGES_HERMES
+PACKAGEDIR_HERMES:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /hermes/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_HERMES),)
+ifneq ($(wildcard $(PACKAGEDIR_HERMES)/units/$(TARGETSUFFIX)),)
+UNITDIR_HERMES=$(PACKAGEDIR_HERMES)/units/$(TARGETSUFFIX)
+else
+UNITDIR_HERMES=$(PACKAGEDIR_HERMES)
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_HERMES)/$(FPCMADE):
+ $(MAKE) -C $(PACKAGEDIR_HERMES) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_HERMES)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_HERMES=
+UNITDIR_HERMES:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /hermes/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_HERMES),)
+UNITDIR_HERMES:=$(firstword $(UNITDIR_HERMES))
+else
+UNITDIR_HERMES=
+endif
+endif
+ifdef UNITDIR_HERMES
+override COMPILER_UNITDIR+=$(UNITDIR_HERMES)
+endif
+endif
+ifdef REQUIRE_PACKAGES_X11
+PACKAGEDIR_X11:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /x11/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_X11),)
+ifneq ($(wildcard $(PACKAGEDIR_X11)/units/$(TARGETSUFFIX)),)
+UNITDIR_X11=$(PACKAGEDIR_X11)/units/$(TARGETSUFFIX)
+else
+UNITDIR_X11=$(PACKAGEDIR_X11)
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_X11)/$(FPCMADE):
+ $(MAKE) -C $(PACKAGEDIR_X11) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_X11)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_X11=
+UNITDIR_X11:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /x11/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_X11),)
+UNITDIR_X11:=$(firstword $(UNITDIR_X11))
+else
+UNITDIR_X11=
+endif
+endif
+ifdef UNITDIR_X11
+override COMPILER_UNITDIR+=$(UNITDIR_X11)
+endif
+endif
+ifdef REQUIRE_PACKAGES_PTC
+PACKAGEDIR_PTC:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /ptc/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_PTC),)
+ifneq ($(wildcard $(PACKAGEDIR_PTC)/units/$(TARGETSUFFIX)),)
+UNITDIR_PTC=$(PACKAGEDIR_PTC)/units/$(TARGETSUFFIX)
+else
+UNITDIR_PTC=$(PACKAGEDIR_PTC)
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_PTC)/$(FPCMADE):
+ $(MAKE) -C $(PACKAGEDIR_PTC) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_PTC)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_PTC=
+UNITDIR_PTC:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /ptc/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_PTC),)
+UNITDIR_PTC:=$(firstword $(UNITDIR_PTC))
+else
+UNITDIR_PTC=
+endif
+endif
+ifdef UNITDIR_PTC
+override COMPILER_UNITDIR+=$(UNITDIR_PTC)
+endif
+endif
+ifndef NOCPUDEF
+override FPCOPTDEF=$(CPU_TARGET)
+endif
+ifneq ($(OS_TARGET),$(OS_SOURCE))
+override FPCOPT+=-T$(OS_TARGET)
+endif
+ifneq ($(CPU_TARGET),$(CPU_SOURCE))
+override FPCOPT+=-P$(CPU_TARGET)
+endif
+ifeq ($(OS_SOURCE),openbsd)
+override FPCOPT+=-FD$(NEW_BINUTILS_PATH)
+endif
+ifndef CROSSBOOTSTRAP
+ifneq ($(BINUTILSPREFIX),)
+override FPCOPT+=-XP$(BINUTILSPREFIX)
+endif
+ifneq ($(BINUTILSPREFIX),)
+override FPCOPT+=-Xr$(RLINKPATH)
+endif
+endif
+ifdef UNITDIR
+override FPCOPT+=$(addprefix -Fu,$(UNITDIR))
+endif
+ifdef LIBDIR
+override FPCOPT+=$(addprefix -Fl,$(LIBDIR))
+endif
+ifdef OBJDIR
+override FPCOPT+=$(addprefix -Fo,$(OBJDIR))
+endif
+ifdef INCDIR
+override FPCOPT+=$(addprefix -Fi,$(INCDIR))
+endif
+ifdef LINKSMART
+override FPCOPT+=-XX
+endif
+ifdef CREATESMART
+override FPCOPT+=-CX
+endif
+ifdef DEBUG
+override FPCOPT+=-gl
+override FPCOPTDEF+=DEBUG
+endif
+ifdef RELEASE
+ifneq ($(findstring 2.0.,$(FPC_VERSION)),)
+ifeq ($(CPU_TARGET),i386)
+FPCCPUOPT:=-OG2p3
+endif
+ifeq ($(CPU_TARGET),powerpc)
+FPCCPUOPT:=-O1r
+endif
+else
+FPCCPUOPT:=-O2
+endif
+override FPCOPT+=-Ur -Xs $(FPCCPUOPT) -n
+override FPCOPTDEF+=RELEASE
+endif
+ifdef STRIP
+override FPCOPT+=-Xs
+endif
+ifdef OPTIMIZE
+override FPCOPT+=-O2
+endif
+ifdef VERBOSE
+override FPCOPT+=-vwni
+endif
+ifdef COMPILER_OPTIONS
+override FPCOPT+=$(COMPILER_OPTIONS)
+endif
+ifdef COMPILER_UNITDIR
+override FPCOPT+=$(addprefix -Fu,$(COMPILER_UNITDIR))
+endif
+ifdef COMPILER_LIBRARYDIR
+override FPCOPT+=$(addprefix -Fl,$(COMPILER_LIBRARYDIR))
+endif
+ifdef COMPILER_OBJECTDIR
+override FPCOPT+=$(addprefix -Fo,$(COMPILER_OBJECTDIR))
+endif
+ifdef COMPILER_INCLUDEDIR
+override FPCOPT+=$(addprefix -Fi,$(COMPILER_INCLUDEDIR))
+endif
+ifdef CROSSBINDIR
+override FPCOPT+=-FD$(CROSSBINDIR)
+endif
+ifdef COMPILER_TARGETDIR
+override FPCOPT+=-FE$(COMPILER_TARGETDIR)
+ifeq ($(COMPILER_TARGETDIR),.)
+override TARGETDIRPREFIX=
+else
+override TARGETDIRPREFIX=$(COMPILER_TARGETDIR)/
+endif
+endif
+ifdef COMPILER_UNITTARGETDIR
+override FPCOPT+=-FU$(COMPILER_UNITTARGETDIR)
+ifeq ($(COMPILER_UNITTARGETDIR),.)
+override UNITTARGETDIRPREFIX=
+else
+override UNITTARGETDIRPREFIX=$(COMPILER_UNITTARGETDIR)/
+endif
+else
+ifdef COMPILER_TARGETDIR
+override COMPILER_UNITTARGETDIR=$(COMPILER_TARGETDIR)
+override UNITTARGETDIRPREFIX=$(TARGETDIRPREFIX)
+endif
+endif
+ifdef CREATESHARED
+override FPCOPT+=-Cg
+ifeq ($(CPU_TARGET),i386)
+override FPCOPT+=-Aas
+endif
+endif
+ifeq ($(findstring 2.0.,$(FPC_VERSION)),)
+ifeq ($(OS_TARGET),linux)
+ifeq ($(CPU_TARGET),x86_64)
+override FPCOPT+=-Cg
+endif
+endif
+endif
+ifdef LINKSHARED
+endif
+ifdef GCCLIBDIR
+override FPCOPT+=-Fl$(GCCLIBDIR)
+endif
+ifdef OTHERLIBDIR
+override FPCOPT+=$(addprefix -Fl,$(OTHERLIBDIR))
+endif
+ifdef OPT
+override FPCOPT+=$(OPT)
+endif
+ifdef FPCOPTDEF
+override FPCOPT+=$(addprefix -d,$(FPCOPTDEF))
+endif
+ifdef CFGFILE
+override FPCOPT+=@$(CFGFILE)
+endif
+ifdef USEENV
+override FPCEXTCMD:=$(FPCOPT)
+override FPCOPT:=!FPCEXTCMD
+export FPCEXTCMD
+endif
+override AFULL_TARGET=$(CPU_TARGET)-$(OS_TARGET)
+override AFULL_SOURCE=$(CPU_SOURCE)-$(OS_SOURCE)
+ifneq ($(AFULL_TARGET),$(AFULL_SOURCE))
+override ACROSSCOMPILE=1
+endif
+ifdef ACROSSCOMPILE
+override FPCOPT+=$(CROSSOPT)
+endif
+override COMPILER:=$(FPC) $(FPCOPT)
+ifeq (,$(findstring -s ,$(COMPILER)))
+EXECPPAS=
+else
+ifeq ($(FULL_SOURCE),$(FULL_TARGET))
+ifdef RUNBATCH
+EXECPPAS:=@$(RUNBATCH) $(PPAS)
+else
+EXECPPAS:=@$(PPAS)
+endif
+endif
+endif
+.PHONY: fpc_exes
+ifndef CROSSINSTALL
+ifneq ($(TARGET_PROGRAMS),)
+override EXEFILES=$(addsuffix $(EXEEXT),$(TARGET_PROGRAMS))
+override EXEOFILES:=$(addsuffix $(OEXT),$(TARGET_PROGRAMS)) $(addprefix $(STATICLIBPREFIX),$(addsuffix $(STATICLIBEXT),$(TARGET_PROGRAMS))) $(addprefix $(IMPORTLIBPREFIX),$(addsuffix $(STATICLIBEXT),$(TARGET_PROGRAMS)))
+override ALLTARGET+=fpc_exes
+override INSTALLEXEFILES+=$(EXEFILES)
+override CLEANEXEFILES+=$(EXEFILES) $(EXEOFILES)
+ifeq ($(OS_TARGET),os2)
+override CLEANEXEFILES+=$(addsuffix $(AOUTEXT),$(TARGET_PROGRAMS))
+endif
+ifeq ($(OS_TARGET),emx)
+override CLEANEXEFILES+=$(addsuffix $(AOUTEXT),$(TARGET_PROGRAMS))
+endif
+endif
+endif
+fpc_exes: $(COMPILER_TARGETDIR) $(COMPILER_UNITTARGETDIR) $(EXEFILES)
+ifdef TARGET_RSTS
+override RSTFILES=$(addsuffix $(RSTEXT),$(TARGET_RSTS))
+override CLEANRSTFILES+=$(RSTFILES)
+endif
+.PHONY: fpc_all fpc_smart fpc_debug fpc_release fpc_shared
+$(FPCMADE): $(ALLDEPENDENCIES) $(ALLTARGET)
+ @$(ECHOREDIR) Compiled > $(FPCMADE)
+fpc_all: $(FPCMADE)
+fpc_smart:
+ $(MAKE) all LINKSMART=1 CREATESMART=1
+fpc_debug:
+ $(MAKE) all DEBUG=1
+fpc_release:
+ $(MAKE) all RELEASE=1
+.SUFFIXES: $(EXEEXT) $(PPUEXT) $(OEXT) .pas .lpr .dpr .pp .rc .res
+$(COMPILER_UNITTARGETDIR):
+ $(MKDIRTREE) $(COMPILER_UNITTARGETDIR)
+$(COMPILER_TARGETDIR):
+ $(MKDIRTREE) $(COMPILER_TARGETDIR)
+%$(PPUEXT): %.pp
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(PPUEXT): %.pas
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(EXEEXT): %.pp
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(EXEEXT): %.pas
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(EXEEXT): %.lpr
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(EXEEXT): %.dpr
+ $(COMPILER) $<
+ $(EXECPPAS)
+%.res: %.rc
+ windres -i $< -o $@
+vpath %.pp $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.pas $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.lpr $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.dpr $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.inc $(COMPILER_INCLUDEDIR)
+vpath %$(OEXT) $(COMPILER_UNITTARGETDIR)
+vpath %$(PPUEXT) $(COMPILER_UNITTARGETDIR)
+.PHONY: fpc_shared
+override INSTALLTARGET+=fpc_shared_install
+ifndef SHARED_LIBVERSION
+SHARED_LIBVERSION=$(FPC_VERSION)
+endif
+ifndef SHARED_LIBNAME
+SHARED_LIBNAME=$(PACKAGE_NAME)
+endif
+ifndef SHARED_FULLNAME
+SHARED_FULLNAME=$(SHAREDLIBPREFIX)$(SHARED_LIBNAME)-$(SHARED_LIBVERSION)$(SHAREDLIBEXT)
+endif
+ifndef SHARED_LIBUNITS
+SHARED_LIBUNITS:=$(TARGET_UNITS) $(TARGET_IMPLICITUNITS)
+override SHARED_LIBUNITS:=$(filter-out $(INSTALL_BUILDUNIT),$(SHARED_LIBUNITS))
+endif
+fpc_shared:
+ifdef HASSHAREDLIB
+ $(MAKE) all CREATESHARED=1 LINKSHARED=1 CREATESMART=1
+ifneq ($(SHARED_BUILD),n)
+ $(PPUMOVE) -q $(SHARED_LIBUNITS) -i$(COMPILER_UNITTARGETDIR) -o$(SHARED_FULLNAME) -d$(COMPILER_UNITTARGETDIR)
+endif
+else
+ @$(ECHO) Shared Libraries not supported
+endif
+fpc_shared_install:
+ifneq ($(SHARED_BUILD),n)
+ifneq ($(SHARED_LIBUNITS),)
+ifneq ($(wildcard $(COMPILER_UNITTARGETDIR)/$(SHARED_FULLNAME)),)
+ $(INSTALL) $(COMPILER_UNITTARGETDIR)/$(SHARED_FULLNAME) $(INSTALL_SHAREDDIR)
+endif
+endif
+endif
+.PHONY: fpc_install fpc_sourceinstall fpc_exampleinstall
+ifdef INSTALL_UNITS
+override INSTALLPPUFILES+=$(addsuffix $(PPUEXT),$(INSTALL_UNITS))
+endif
+ifdef INSTALL_BUILDUNIT
+override INSTALLPPUFILES:=$(filter-out $(INSTALL_BUILDUNIT)$(PPUEXT),$(INSTALLPPUFILES))
+endif
+ifdef INSTALLPPUFILES
+override INSTALLPPULINKFILES:=$(subst $(PPUEXT),$(OEXT),$(INSTALLPPUFILES)) $(addprefix $(STATICLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(INSTALLPPUFILES))) $(addprefix $(IMPORTLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(INSTALLPPUFILES)))
+ifneq ($(UNITTARGETDIRPREFIX),)
+override INSTALLPPUFILES:=$(addprefix $(UNITTARGETDIRPREFIX),$(notdir $(INSTALLPPUFILES)))
+override INSTALLPPULINKFILES:=$(wildcard $(addprefix $(UNITTARGETDIRPREFIX),$(notdir $(INSTALLPPULINKFILES))))
+endif
+override INSTALL_CREATEPACKAGEFPC=1
+endif
+ifdef INSTALLEXEFILES
+ifneq ($(TARGETDIRPREFIX),)
+override INSTALLEXEFILES:=$(addprefix $(TARGETDIRPREFIX),$(notdir $(INSTALLEXEFILES)))
+endif
+endif
+fpc_install: all $(INSTALLTARGET)
+ifdef INSTALLEXEFILES
+ $(MKDIR) $(INSTALL_BINDIR)
+ifdef UPXPROG
+ -$(UPXPROG) $(INSTALLEXEFILES)
+endif
+ $(INSTALLEXE) $(INSTALLEXEFILES) $(INSTALL_BINDIR)
+endif
+ifdef INSTALL_CREATEPACKAGEFPC
+ifdef FPCMAKE
+ifdef PACKAGE_VERSION
+ifneq ($(wildcard Makefile.fpc),)
+ $(FPCMAKE) -p -T$(CPU_TARGET)-$(OS_TARGET) Makefile.fpc
+ $(MKDIR) $(INSTALL_UNITDIR)
+ $(INSTALL) Package.fpc $(INSTALL_UNITDIR)
+endif
+endif
+endif
+endif
+ifdef INSTALLPPUFILES
+ $(MKDIR) $(INSTALL_UNITDIR)
+ $(INSTALL) $(INSTALLPPUFILES) $(INSTALL_UNITDIR)
+ifneq ($(INSTALLPPULINKFILES),)
+ $(INSTALL) $(INSTALLPPULINKFILES) $(INSTALL_UNITDIR)
+endif
+ifneq ($(wildcard $(LIB_FULLNAME)),)
+ $(MKDIR) $(INSTALL_LIBDIR)
+ $(INSTALL) $(LIB_FULLNAME) $(INSTALL_LIBDIR)
+ifdef inUnix
+ ln -sf $(LIB_FULLNAME) $(INSTALL_LIBDIR)/$(LIB_NAME)
+endif
+endif
+endif
+ifdef INSTALL_FILES
+ $(MKDIR) $(INSTALL_DATADIR)
+ $(INSTALL) $(INSTALL_FILES) $(INSTALL_DATADIR)
+endif
+fpc_sourceinstall: distclean
+ $(MKDIR) $(INSTALL_SOURCEDIR)
+ $(COPYTREE) $(BASEDIR)/* $(INSTALL_SOURCEDIR)
+fpc_exampleinstall: $(addsuffix _distclean,$(TARGET_EXAMPLEDIRS))
+ifdef HASEXAMPLES
+ $(MKDIR) $(INSTALL_EXAMPLEDIR)
+endif
+ifdef EXAMPLESOURCEFILES
+ $(COPY) $(EXAMPLESOURCEFILES) $(INSTALL_EXAMPLEDIR)
+endif
+ifdef TARGET_EXAMPLEDIRS
+ $(COPYTREE) $(addsuffix /*,$(TARGET_EXAMPLEDIRS)) $(INSTALL_EXAMPLEDIR)
+endif
+.PHONY: fpc_distinstall
+fpc_distinstall: install exampleinstall
+.PHONY: fpc_zipinstall fpc_zipsourceinstall fpc_zipexampleinstall
+ifndef PACKDIR
+ifndef inUnix
+PACKDIR=$(BASEDIR)/../fpc-pack
+else
+PACKDIR=/tmp/fpc-pack
+endif
+endif
+ifndef ZIPNAME
+ifdef DIST_ZIPNAME
+ZIPNAME=$(DIST_ZIPNAME)
+else
+ZIPNAME=$(PACKAGE_NAME)
+endif
+endif
+ifndef FULLZIPNAME
+FULLZIPNAME=$(ZIPCROSSPREFIX)$(ZIPPREFIX)$(ZIPNAME)$(ZIPSUFFIX)
+endif
+ifndef ZIPTARGET
+ifdef DIST_ZIPTARGET
+ZIPTARGET=DIST_ZIPTARGET
+else
+ZIPTARGET=install
+endif
+endif
+ifndef USEZIP
+ifdef inUnix
+USETAR=1
+endif
+endif
+ifndef inUnix
+USEZIPWRAPPER=1
+endif
+ifdef USEZIPWRAPPER
+ZIPPATHSEP=$(PATHSEP)
+ZIPWRAPPER=$(subst /,$(PATHSEP),$(DIST_DESTDIR)/fpczip$(SRCBATCHEXT))
+else
+ZIPPATHSEP=/
+endif
+ZIPCMD_CDPACK:=cd $(subst /,$(ZIPPATHSEP),$(PACKDIR))
+ZIPCMD_CDBASE:=cd $(subst /,$(ZIPPATHSEP),$(BASEDIR))
+ifdef USETAR
+ZIPDESTFILE:=$(DIST_DESTDIR)/$(FULLZIPNAME)$(TAREXT)
+ZIPCMD_ZIP:=$(TARPROG) cf$(TAROPT) $(ZIPDESTFILE) *
+else
+ZIPDESTFILE:=$(DIST_DESTDIR)/$(FULLZIPNAME)$(ZIPEXT)
+ZIPCMD_ZIP:=$(subst /,$(ZIPPATHSEP),$(ZIPPROG)) -Dr $(ZIPOPT) $(ZIPDESTFILE) *
+endif
+fpc_zipinstall:
+ $(MAKE) $(ZIPTARGET) INSTALL_PREFIX=$(PACKDIR) ZIPINSTALL=1
+ $(MKDIR) $(DIST_DESTDIR)
+ $(DEL) $(ZIPDESTFILE)
+ifdef USEZIPWRAPPER
+ifneq ($(ECHOREDIR),echo)
+ $(ECHOREDIR) -e "$(subst \,\\,$(ZIPCMD_CDPACK))" > $(ZIPWRAPPER)
+ $(ECHOREDIR) -e "$(subst \,\\,$(ZIPCMD_ZIP))" >> $(ZIPWRAPPER)
+ $(ECHOREDIR) -e "$(subst \,\\,$(ZIPCMD_CDBASE))" >> $(ZIPWRAPPER)
+else
+ echo $(ZIPCMD_CDPACK) > $(ZIPWRAPPER)
+ echo $(ZIPCMD_ZIP) >> $(ZIPWRAPPER)
+ echo $(ZIPCMD_CDBASE) >> $(ZIPWRAPPER)
+endif
+ifdef inUnix
+ /bin/sh $(ZIPWRAPPER)
+else
+ifdef RUNBATCH
+ $(RUNBATCH) (ZIPWRAPPER)
+else
+ $(ZIPWRAPPER)
+endif
+endif
+ $(DEL) $(ZIPWRAPPER)
+else
+ $(ZIPCMD_CDPACK) ; $(ZIPCMD_ZIP) ; $(ZIPCMD_CDBASE)
+endif
+ $(DELTREE) $(PACKDIR)
+fpc_zipsourceinstall:
+ $(MAKE) fpc_zipinstall ZIPTARGET=sourceinstall ZIPSUFFIX=$(ZIPSOURCESUFFIX)
+fpc_zipexampleinstall:
+ifdef HASEXAMPLES
+ $(MAKE) fpc_zipinstall ZIPTARGET=exampleinstall ZIPSUFFIX=$(ZIPEXAMPLESUFFIX)
+endif
+fpc_zipdistinstall:
+ $(MAKE) fpc_zipinstall ZIPTARGET=distinstall
+.PHONY: fpc_clean fpc_cleanall fpc_distclean
+ifdef EXEFILES
+override CLEANEXEFILES:=$(addprefix $(TARGETDIRPREFIX),$(CLEANEXEFILES))
+endif
+ifdef CLEAN_UNITS
+override CLEANPPUFILES+=$(addsuffix $(PPUEXT),$(CLEAN_UNITS))
+endif
+ifdef CLEANPPUFILES
+override CLEANPPULINKFILES:=$(subst $(PPUEXT),$(OEXT),$(CLEANPPUFILES)) $(addprefix $(STATICLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(CLEANPPUFILES))) $(addprefix $(IMPORTLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(CLEANPPUFILES)))
+ifdef DEBUGSYMEXT
+override CLEANPPULINKFILES+=$(subst $(PPUEXT),$(DEBUGSYMEXT),$(CLEANPPUFILES))
+endif
+override CLEANPPUFILES:=$(addprefix $(UNITTARGETDIRPREFIX),$(CLEANPPUFILES))
+override CLEANPPULINKFILES:=$(wildcard $(addprefix $(UNITTARGETDIRPREFIX),$(CLEANPPULINKFILES)))
+endif
+fpc_clean: $(CLEANTARGET)
+ifdef CLEANEXEFILES
+ -$(DEL) $(CLEANEXEFILES)
+endif
+ifdef CLEANPPUFILES
+ -$(DEL) $(CLEANPPUFILES)
+endif
+ifneq ($(CLEANPPULINKFILES),)
+ -$(DEL) $(CLEANPPULINKFILES)
+endif
+ifdef CLEANRSTFILES
+ -$(DEL) $(addprefix $(UNITTARGETDIRPREFIX),$(CLEANRSTFILES))
+endif
+ifdef CLEAN_FILES
+ -$(DEL) $(CLEAN_FILES)
+endif
+ifdef LIB_NAME
+ -$(DEL) $(LIB_NAME) $(LIB_FULLNAME)
+endif
+ -$(DEL) $(FPCMADE) Package.fpc $(PPAS) script.res link.res $(FPCEXTFILE) $(REDIRFILE)
+ -$(DEL) *$(ASMEXT) *_ppas$(BATCHEXT)
+fpc_cleanall: $(CLEANTARGET)
+ifdef CLEANEXEFILES
+ -$(DEL) $(CLEANEXEFILES)
+endif
+ifdef COMPILER_UNITTARGETDIR
+ifdef CLEANPPUFILES
+ -$(DEL) $(CLEANPPUFILES)
+endif
+ifneq ($(CLEANPPULINKFILES),)
+ -$(DEL) $(CLEANPPULINKFILES)
+endif
+ifdef CLEANRSTFILES
+ -$(DEL) $(addprefix $(UNITTARGETDIRPREFIX),$(CLEANRSTFILES))
+endif
+endif
+ -$(DELTREE) units
+ -$(DEL) *$(OEXT) *$(PPUEXT) *$(RSTEXT) *$(ASMEXT) *$(STATICLIBEXT) *$(SHAREDLIBEXT) *$(PPLEXT)
+ifneq ($(PPUEXT),.ppu)
+ -$(DEL) *.o *.ppu *.a
+endif
+ -$(DELTREE) *$(SMARTEXT)
+ -$(DEL) fpcmade.* Package.fpc $(PPAS) script.res link.res $(FPCEXTFILE) $(REDIRFILE)
+ -$(DEL) *_ppas$(BATCHEXT)
+ifdef AOUTEXT
+ -$(DEL) *$(AOUTEXT)
+endif
+ifdef DEBUGSYMEXT
+ -$(DEL) *$(DEBUGSYMEXT)
+endif
+fpc_distclean: cleanall
+.PHONY: fpc_baseinfo
+override INFORULES+=fpc_baseinfo
+fpc_baseinfo:
+ @$(ECHO)
+ @$(ECHO) == Package info ==
+ @$(ECHO) Package Name..... $(PACKAGE_NAME)
+ @$(ECHO) Package Version.. $(PACKAGE_VERSION)
+ @$(ECHO)
+ @$(ECHO) == Configuration info ==
+ @$(ECHO)
+ @$(ECHO) FPC.......... $(FPC)
+ @$(ECHO) FPC Version.. $(FPC_VERSION)
+ @$(ECHO) Source CPU... $(CPU_SOURCE)
+ @$(ECHO) Target CPU... $(CPU_TARGET)
+ @$(ECHO) Source OS.... $(OS_SOURCE)
+ @$(ECHO) Target OS.... $(OS_TARGET)
+ @$(ECHO) Full Source.. $(FULL_SOURCE)
+ @$(ECHO) Full Target.. $(FULL_TARGET)
+ @$(ECHO) SourceSuffix. $(SOURCESUFFIX)
+ @$(ECHO) TargetSuffix. $(TARGETSUFFIX)
+ @$(ECHO)
+ @$(ECHO) == Directory info ==
+ @$(ECHO)
+ @$(ECHO) Required pkgs... $(REQUIRE_PACKAGES)
+ @$(ECHO)
+ @$(ECHO) Basedir......... $(BASEDIR)
+ @$(ECHO) FPCDir.......... $(FPCDIR)
+ @$(ECHO) CrossBinDir..... $(CROSSBINDIR)
+ @$(ECHO) UnitsDir........ $(UNITSDIR)
+ @$(ECHO) PackagesDir..... $(PACKAGESDIR)
+ @$(ECHO)
+ @$(ECHO) GCC library..... $(GCCLIBDIR)
+ @$(ECHO) Other library... $(OTHERLIBDIR)
+ @$(ECHO)
+ @$(ECHO) == Tools info ==
+ @$(ECHO)
+ @$(ECHO) As........ $(AS)
+ @$(ECHO) Ld........ $(LD)
+ @$(ECHO) Ar........ $(AR)
+ @$(ECHO) Rc........ $(RC)
+ @$(ECHO)
+ @$(ECHO) Mv........ $(MVPROG)
+ @$(ECHO) Cp........ $(CPPROG)
+ @$(ECHO) Rm........ $(RMPROG)
+ @$(ECHO) GInstall.. $(GINSTALL)
+ @$(ECHO) Echo...... $(ECHO)
+ @$(ECHO) Shell..... $(SHELL)
+ @$(ECHO) Date...... $(DATE)
+ @$(ECHO) FPCMake... $(FPCMAKE)
+ @$(ECHO) PPUMove... $(PPUMOVE)
+ @$(ECHO) Upx....... $(UPXPROG)
+ @$(ECHO) Zip....... $(ZIPPROG)
+ @$(ECHO)
+ @$(ECHO) == Object info ==
+ @$(ECHO)
+ @$(ECHO) Target Loaders........ $(TARGET_LOADERS)
+ @$(ECHO) Target Units.......... $(TARGET_UNITS)
+ @$(ECHO) Target Implicit Units. $(TARGET_IMPLICITUNITS)
+ @$(ECHO) Target Programs....... $(TARGET_PROGRAMS)
+ @$(ECHO) Target Dirs........... $(TARGET_DIRS)
+ @$(ECHO) Target Examples....... $(TARGET_EXAMPLES)
+ @$(ECHO) Target ExampleDirs.... $(TARGET_EXAMPLEDIRS)
+ @$(ECHO)
+ @$(ECHO) Clean Units......... $(CLEAN_UNITS)
+ @$(ECHO) Clean Files......... $(CLEAN_FILES)
+ @$(ECHO)
+ @$(ECHO) Install Units....... $(INSTALL_UNITS)
+ @$(ECHO) Install Files....... $(INSTALL_FILES)
+ @$(ECHO)
+ @$(ECHO) == Install info ==
+ @$(ECHO)
+ @$(ECHO) DateStr.............. $(DATESTR)
+ @$(ECHO) ZipName.............. $(ZIPNAME)
+ @$(ECHO) ZipPrefix............ $(ZIPPREFIX)
+ @$(ECHO) ZipCrossPrefix....... $(ZIPCROSSPREFIX)
+ @$(ECHO) ZipSuffix............ $(ZIPSUFFIX)
+ @$(ECHO) FullZipName.......... $(FULLZIPNAME)
+ @$(ECHO) Install FPC Package.. $(INSTALL_FPCPACKAGE)
+ @$(ECHO)
+ @$(ECHO) Install base dir..... $(INSTALL_BASEDIR)
+ @$(ECHO) Install binary dir... $(INSTALL_BINDIR)
+ @$(ECHO) Install library dir.. $(INSTALL_LIBDIR)
+ @$(ECHO) Install units dir.... $(INSTALL_UNITDIR)
+ @$(ECHO) Install source dir... $(INSTALL_SOURCEDIR)
+ @$(ECHO) Install doc dir...... $(INSTALL_DOCDIR)
+ @$(ECHO) Install example dir.. $(INSTALL_EXAMPLEDIR)
+ @$(ECHO) Install data dir..... $(INSTALL_DATADIR)
+ @$(ECHO)
+ @$(ECHO) Dist destination dir. $(DIST_DESTDIR)
+ @$(ECHO) Dist zip name........ $(DIST_ZIPNAME)
+ @$(ECHO)
+.PHONY: fpc_info
+fpc_info: $(INFORULES)
+.PHONY: fpc_makefile fpc_makefiles fpc_makefile_sub1 fpc_makefile_sub2 \
+ fpc_makefile_dirs
+fpc_makefile:
+ $(FPCMAKE) -w -T$(OS_TARGET) Makefile.fpc
+fpc_makefile_sub1:
+ifdef TARGET_DIRS
+ $(FPCMAKE) -w -T$(OS_TARGET) $(addsuffix /Makefile.fpc,$(TARGET_DIRS))
+endif
+ifdef TARGET_EXAMPLEDIRS
+ $(FPCMAKE) -w -T$(OS_TARGET) $(addsuffix /Makefile.fpc,$(TARGET_EXAMPLEDIRS))
+endif
+fpc_makefile_sub2: $(addsuffix _makefile_dirs,$(TARGET_DIRS) $(TARGET_EXAMPLEDIRS))
+fpc_makefile_dirs: fpc_makefile_sub1 fpc_makefile_sub2
+fpc_makefiles: fpc_makefile fpc_makefile_dirs
+all: fpc_all
+debug: fpc_debug
+smart: fpc_smart
+release: fpc_release
+units: fpc_units
+examples:
+shared: fpc_shared
+install: fpc_install
+sourceinstall: fpc_sourceinstall
+exampleinstall: fpc_exampleinstall
+distinstall: fpc_distinstall
+zipinstall: fpc_zipinstall
+zipsourceinstall: fpc_zipsourceinstall
+zipexampleinstall: fpc_zipexampleinstall
+zipdistinstall: fpc_zipdistinstall
+clean: fpc_clean
+distclean: fpc_distclean
+cleanall: fpc_cleanall
+info: fpc_info
+makefiles: fpc_makefiles
+.PHONY: all debug smart release units examples shared install sourceinstall exampleinstall distinstall zipinstall zipsourceinstall zipexampleinstall zipdistinstall clean distclean cleanall info makefiles
+ifneq ($(wildcard fpcmake.loc),)
+include fpcmake.loc
+endif
+.NOTPARALLEL:
diff --git a/packages/ptc/examples/Makefile.fpc b/packages/ptc/examples/Makefile.fpc
new file mode 100644
index 0000000000..a32cdaf4eb
--- /dev/null
+++ b/packages/ptc/examples/Makefile.fpc
@@ -0,0 +1,27 @@
+#
+# Makefile.fpc for PTC examples
+#
+
+[package]
+name=ptc-examples
+version=0.99.5
+
+[target]
+programs=area buffer clear clip con_info console fire \
+ flower hicolor image keyboard keybrd2 land \
+ lights modes mojo palette pixel random save \
+ stretch texwarp timer tunnel3d tunnel
+
+[compiler]
+unitdir=../$(UNITTARGETDIRPREFIX)
+
+[default]
+fpcdir=../../..
+
+[require]
+packages=hermes ptc
+packages_linux=x11
+packages_freebsd=x11
+
+[rules]
+.NOTPARALLEL:
diff --git a/packages/ptc/examples/area.pp b/packages/ptc/examples/area.pp
new file mode 100644
index 0000000000..48e11a9696
--- /dev/null
+++ b/packages/ptc/examples/area.pp
@@ -0,0 +1,100 @@
+{
+Ported to FPC by Nikolay Nikolov (nickysn@users.sourceforge.net)
+}
+
+{
+ Area example for OpenPTC 1.0 C++ Implementation
+ Copyright (c) Glenn Fiedler (ptc@gaffer.org)
+ This source code is in the public domain
+}
+
+Program AreaExample;
+
+{$MODE objfpc}
+
+Uses
+ ptc;
+
+Var
+ console : TPTCConsole;
+ format : TPTCFormat;
+ surface : TPTCSurface;
+ pixels : PDWord;
+ width, height : Integer;
+ i : Integer;
+ x, y, r, g, b : Integer;
+ area : TPTCArea;
+
+Begin
+ area := Nil;
+ format := Nil;
+ surface := Nil;
+ console := Nil;
+ Try
+ Try
+ { create console }
+ console := TPTCConsole.Create;
+
+ { create format }
+ format := TPTCFormat.Create(32, $00FF0000, $0000FF00, $000000FF);
+
+ { create console }
+ console.open('Area example', format);
+
+ { create surface half the size of the console }
+ surface := TPTCSurface.Create(console.width Div 2, console.height Div 2, format);
+
+ { setup destination area }
+ x := console.width Div 4;
+ y := console.height Div 4;
+ area := TPTCArea.Create(x, y, x + surface.width, y + surface.height);
+
+ { loop until a key is pressed }
+ While Not console.KeyPressed Do
+ Begin
+ { lock surface }
+ pixels := surface.lock;
+ Try
+ { get surface dimensions }
+ width := surface.width;
+ height := surface.height;
+
+ { draw random pixels }
+ For i := 1 To 100 Do
+ Begin
+ { get random position }
+ x := Random(width);
+ y := Random(height);
+
+ { get random color }
+ r := Random(256);
+ g := Random(256);
+ b := Random(256);
+
+ { draw color [r,g,b] at position [x,y] }
+ pixels[x + y * width] := (r Shl 16) + (g Shl 8) + b;
+ End;
+ Finally
+ { unlock surface }
+ surface.unlock;
+ End;
+
+ { copy surface to console destination area }
+ surface.copy(console, surface.area, area);
+
+ { update console area }
+ console.update;
+ End;
+ Finally
+ console.close;
+ console.Free;
+ surface.Free;
+ format.Free;
+ area.Free;
+ End;
+ Except
+ On error : TPTCError Do
+ { report error }
+ error.report;
+ End;
+End.
diff --git a/packages/ptc/examples/buffer.pp b/packages/ptc/examples/buffer.pp
new file mode 100644
index 0000000000..de8728d6f3
--- /dev/null
+++ b/packages/ptc/examples/buffer.pp
@@ -0,0 +1,90 @@
+{
+Ported to FPC by Nikolay Nikolov (nickysn@users.sourceforge.net)
+}
+
+{
+ Buffer example for OpenPTC 1.0 C++ Implementation
+ Copyright (c) Glenn Fiedler (ptc@gaffer.org)
+ This source code is in the public domain
+}
+
+Program BufferExample;
+
+{$MODE objfpc}
+
+Uses
+ ptc;
+
+Var
+ console : TPTCConsole;
+ format : TPTCFormat;
+ palette : TPTCPalette;
+ width, height : Integer;
+ pixels : Pint32;
+ x, y, r, g, b : Integer;
+ i : Integer;
+
+Begin
+ pixels := Nil;
+ format := Nil;
+ palette := Nil;
+ console := Nil;
+ Try
+ Try
+ { create console }
+ console := TPTCConsole.Create;
+
+ { create format }
+ format := TPTCFormat.Create(32, $00FF0000, $0000FF00, $000000FF);
+
+ { open the console }
+ console.open('Buffer example', format);
+
+ { get console dimensions }
+ width := console.width;
+ height := console.height;
+
+ { allocate a buffer of pixels }
+ pixels := GetMem(width * height * SizeOf(int32));
+ palette := TPTCPalette.Create;
+
+ { loop until a key is pressed }
+ While Not console.KeyPressed Do
+ Begin
+ { draw random pixels }
+ For i := 1 To 100 Do
+ Begin
+ { get random position }
+ x := Random(width);
+ y := Random(height);
+
+ { get random color }
+ r := Random(256);
+ g := Random(256);
+ b := Random(256);
+
+ { draw color [r,g,b] at position [x,y] }
+ pixels[x + y * width] := (r Shl 16) Or (g Shl 8) Or b;
+ End;
+
+ { load pixels to console }
+ console.load(pixels, width, height, width * 4, format, palette);
+
+ { update console }
+ console.update;
+ End;
+ Finally
+ { free pixels buffer }
+ If Assigned(pixels) Then
+ FreeMem(pixels);
+ console.close;
+ palette.Free;
+ format.Free;
+ console.Free;
+ End;
+ Except
+ On error : TPTCError Do
+ { report error }
+ error.report;
+ End;
+End.
diff --git a/packages/ptc/examples/clear.pp b/packages/ptc/examples/clear.pp
new file mode 100644
index 0000000000..d63e4c1f82
--- /dev/null
+++ b/packages/ptc/examples/clear.pp
@@ -0,0 +1,81 @@
+{
+Ported to FPC by Nikolay Nikolov (nickysn@users.sourceforge.net)
+}
+
+{
+ Clear example for OpenPTC 1.0 C++ Implementation
+ Copyright (c) Glenn Fiedler (ptc@gaffer.org)
+ This source code is in the public domain
+}
+
+Program ClearExample;
+
+{$MODE objfpc}
+
+Uses
+ ptc;
+
+Var
+ console : TPTCConsole;
+ format : TPTCFormat;
+ surface : TPTCSurface;
+ width, height : Integer;
+ x, y : Integer;
+ size : Integer;
+ area : TPTCArea;
+ color : TPTCColor;
+
+Begin
+ Try
+ { create console }
+ console := TPTCConsole.Create;
+
+ { create format }
+ format := TPTCFormat.Create(32, $00FF0000, $0000FF00, $000000FF);
+
+ { open the console }
+ console.open('Clear example', format);
+
+ { create surface matching console dimensions }
+ surface := TPTCSurface.Create(console.width, console.height, format);
+
+ { loop until a key is pressed }
+ While Not console.KeyPressed Do
+ Begin
+ { get surface dimensions }
+ width := surface.width;
+ height := surface.height;
+
+ { get random position }
+ x := Random(width);
+ y := Random(height);
+
+ { get random area size }
+ size := Random(width Div 8);
+
+ { setup clear area }
+ area := TPTCArea.Create(x-size, y-size, x+size, y+size);
+
+ { create random color }
+ color := TPTCColor.Create(Random, Random, Random);
+
+ { clear surface area with color }
+ surface.clear(color, area);
+
+ { copy to console }
+ surface.copy(console);
+
+ { update console }
+ console.update;
+ area.Free;
+ color.Free;
+ End;
+ console.close;
+ console.Free;
+ surface.Free;
+ Except
+ On error : TPTCError Do
+ { report error }
+ error.report;
+ End;
+End.
diff --git a/packages/ptc/examples/clip.pp b/packages/ptc/examples/clip.pp
new file mode 100644
index 0000000000..2104b912cb
--- /dev/null
+++ b/packages/ptc/examples/clip.pp
@@ -0,0 +1,109 @@
+{
+Ported to FPC by Nikolay Nikolov (nickysn@users.sourceforge.net)
+}
+
+{
+ Clip example for OpenPTC 1.0 C++ Implementation
+ Copyright (c) Glenn Fiedler (ptc@gaffer.org)
+ This source code is in the public domain
+}
+
+Program ClipExample;
+
+{$MODE objfpc}
+
+Uses
+ ptc;
+
+Var
+ console : TPTCConsole;
+ surface : TPTCSurface;
+ format : TPTCFormat;
+ area : TPTCArea;
+ x1, y1, x2, y2 : Integer;
+ pixels : Pint32;
+ width, height : Integer;
+ i : Integer;
+ x, y, r, g, b : Integer;
+
+Begin
+ format := Nil;
+ surface := Nil;
+ console := Nil;
+ Try
+ Try
+ { create console }
+ console := TPTCConsole.Create;
+
+ { create format }
+ format := TPTCFormat.Create(32, $00FF0000, $0000FF00, $000000FF);
+
+ { open the console }
+ console.open('Clip example', format);
+
+ { create surface matching console dimensions }
+ surface := TPTCSurface.Create(console.width, console.height, format);
+
+ { calculate clip coordinates }
+ x1 := console.width Div 4;
+ y1 := console.height Div 4;
+ x2 := console.width - x1;
+ y2 := console.height - y1;
+
+ { setup clip area }
+ area := TPTCArea.Create(x1, y1, x2, y2);
+ Try
+ { set clip area }
+ console.clip(area);
+ Finally
+ area.Free;
+ End;
+
+ { loop until a key is pressed }
+ While Not console.KeyPressed Do
+ Begin
+ { lock surface }
+ pixels := surface.lock;
+ Try
+ { get surface dimensions }
+ width := surface.width;
+ height := surface.height;
+
+ { draw random pixels }
+ For i := 1 To 100 Do
+ Begin
+ { get random position }
+ x := Random(width);
+ y := Random(height);
+
+ { get random color }
+ r := Random(256);
+ g := Random(256);
+ b := Random(256);
+
+ { draw color [r,g,b] at position [x,y] }
+ pixels[x + y * width] := (r Shl 16) + (g Shl 8) + b;
+ End;
+ Finally
+ { unlock surface }
+ surface.unlock;
+ End;
+
+ { copy to console }
+ surface.copy(console);
+
+ { update console }
+ console.update;
+ End;
+ Finally
+ console.close;
+ console.Free;
+ surface.Free;
+ format.Free;
+ End;
+ Except
+ On error : TPTCError Do
+ { report error }
+ error.report;
+ End;
+End.
diff --git a/packages/ptc/examples/con_info.pp b/packages/ptc/examples/con_info.pp
new file mode 100644
index 0000000000..86151ecc23
--- /dev/null
+++ b/packages/ptc/examples/con_info.pp
@@ -0,0 +1,78 @@
+{
+Ported to FPC by Nikolay Nikolov (nickysn@users.sourceforge.net)
+}
+
+{
+ Info example for OpenPTC 1.0 C++ Implementation
+ Copyright (c) Glenn Fiedler (ptc@gaffer.org)
+ This source code is in the public domain
+}
+
+Program InfoExample;
+
+{$MODE objfpc}
+
+Uses
+ ptc;
+
+Procedure print(Const format : TPTCFormat);
+
+Begin
+ { check format type }
+ If format.direct Then
+ { check alpha }
+ If format.a = 0 Then
+ { direct color format without alpha }
+ Write('Format(', format.bits:2, ',$', HexStr(format.r, 8), ',$', HexStr(format.g, 8), ',$', HexStr(format.b, 8), ')')
+ Else
+ { direct color format with alpha }
+ Write('Format(', format.bits:2, ',$', HexStr(format.r, 8), ',$', HexStr(format.g, 8), ',$', HexStr(format.b, 8), ',$', HexStr(format.a, 8), ')')
+ Else
+ { indexed color format }
+ Write('Format(', format.bits:2, ')');
+End;
+
+Var
+ console : TPTCConsole;
+
+Begin
+ console := Nil;
+ Try
+ Try
+ Writeln('[ptc version]');
+ { print ptc version string define }
+ Writeln(PTC_VERSION);
+ Writeln;
+
+ { create console }
+ console := TPTCConsole.Create;
+
+ { open the console }
+ console.open('Info example');
+
+ { print console data }
+ Writeln('[console data]');
+ Writeln('name = ', console.name);
+ Writeln('title = ', console.title);
+ Writeln('width = ', console.width);
+ Writeln('height = ', console.height);
+ Writeln('pages = ', console.pages);
+ Writeln('pitch = ', console.pitch);
+ Write('format = ');
+ print(console.format);
+ Writeln;
+ Writeln;
+
+ { print console information }
+ Writeln('[console information]');
+ Writeln(console.information);
+ Finally
+ console.close;
+ console.Free;
+ End;
+ Except
+ On error : TPTCError Do
+ { report error }
+ error.report;
+ End;
+End.
diff --git a/packages/ptc/examples/console.pp b/packages/ptc/examples/console.pp
new file mode 100644
index 0000000000..642b1765f8
--- /dev/null
+++ b/packages/ptc/examples/console.pp
@@ -0,0 +1,119 @@
+{
+Ported to FPC by Nikolay Nikolov (nickysn@users.sourceforge.net)
+}
+
+{
+ Console example for OpenPTC 1.0 C++ Implementation
+ Copyright (c) Glenn Fiedler (ptc@gaffer.org)
+ This source code is in the public domain
+}
+
+Program ConsoleExample;
+
+{$MODE objfpc}
+
+Uses
+ ptc;
+
+Var
+ console : TPTCConsole;
+ palette : TPTCPalette;
+ data : Array[0..255] Of DWord;
+ i : Integer;
+ pixels : PByte;
+ width, height, pitch : Integer;
+ format : TPTCFormat;
+ bits, bytes : Integer;
+ x, y : Integer;
+ color : DWord;
+ pixel : PByte;
+ _data : PByte;
+
+Begin
+ Try
+ { create console }
+ console := TPTCConsole.Create;
+
+ { open the console with one page }
+ console.open('Console example', 1);
+
+ { create palette }
+ palette := TPTCPalette.Create;
+
+ { generate palette }
+ For i := 0 To 255 Do
+ data[i] := i;
+
+ { load palette data }
+ palette.load(data);
+
+ { set console palette }
+ console.palette(palette);
+
+ { loop until a key is pressed }
+ While Not console.KeyPressed Do
+ Begin
+ { lock console }
+ pixels := console.lock;
+
+ { get console dimensions }
+ width := console.width;
+ height := console.height;
+ pitch := console.pitch;
+
+ { get console format }
+ format := console.format;
+
+ { get format information }
+ bits := format.bits;
+ bytes := format.bytes;
+
+ { draw random pixels }
+ For i := 1 To 100 Do
+ Begin
+ { get random position }
+ x := Random(width);
+ y := Random(height);
+
+ { generate random color integer }
+ color := (Random(256) Shl 0) Or
+ (Random(256) Shl 8) Or
+ (Random(256) Shl 16) Or
+ (Random(256) Shl 24);
+
+ { calculate pointer to pixel [x,y] }
+ pixel := pixels + y * pitch + x * bytes;
+
+ { check bits }
+ Case bits Of
+ { 32 bits per pixel }
+ 32 : PDWord(pixel)^ := color;
+ 24 : Begin
+ { 24 bits per pixel }
+ _data := pixel;
+ _data[0] := (color And $000000FF) Shr 0;
+ _data[1] := (color And $0000FF00) Shr 8;
+ _data[2] := (color And $00FF0000) Shr 16;
+ End;
+ { 16 bits per pixel }
+ 16 : PWord(pixel)^ := color;
+ { 8 bits per pixel }
+ 8 : PByte(pixel)^ := color;
+ End;
+ End;
+
+ { unlock console }
+ console.unlock;
+
+ { update console }
+ console.update;
+ End;
+ palette.Free;
+ console.close;
+ console.Free;
+ Except
+ On error : TPTCError Do
+ { report error }
+ error.report;
+ End;
+End.
diff --git a/packages/ptc/examples/fire.pp b/packages/ptc/examples/fire.pp
new file mode 100644
index 0000000000..4f5c647c99
--- /dev/null
+++ b/packages/ptc/examples/fire.pp
@@ -0,0 +1,265 @@
+{
+Ported to FPC by Nikolay Nikolov (nickysn@users.sourceforge.net)
+}
+
+{
+ Fire demo for OpenPTC 1.0 C++ API
+ Copyright (c) Glenn Fiedler (ptc@gaffer.org)
+ This source code is licensed under the GNU GPL
+}
+
+Program Fire;
+
+{$MODE objfpc}
+
+Uses
+ ptc;
+
+Function pack(r, g, b : Uint32) : Uint32;
+
+Begin
+ { pack color integer }
+ pack := (r Shl 16) Or (g Shl 8) Or b;
+End;
+
+Procedure generate(palette : TPTCPalette);
+
+Var
+ data : PUint32;
+ i, c : Integer;
+
+Begin
+ { lock palette data }
+ data := palette.lock;
+
+ Try
+ { black to red }
+ i := 0;
+ c := 0;
+ While i < 64 Do
+ Begin
+ data[i] := pack(c, 0, 0);
+ Inc(c, 4);
+ Inc(i);
+ End;
+
+ { red to yellow }
+ c := 0;
+ While i < 128 Do
+ Begin
+ data[i] := pack(255, c, 0);
+ Inc(c, 4);
+ Inc(i);
+ End;
+
+ { yellow to white }
+ c := 0;
+ While i < {192}128 Do
+ Begin
+ data[i] := pack(255, 255, c);
+ Inc(c, 4);
+ Inc(i);
+ End;
+
+ { white }
+ While i < 256 Do
+ Begin
+ data[i] := pack(255, 255, 255);
+ Inc(i);
+ End;
+
+ Finally
+ { unlock palette }
+ palette.unlock;
+ End;
+End;
+
+Var
+ format : TPTCFormat;
+ console : TPTCConsole;
+ surface : TPTCSurface;
+ palette : TPTCPalette;
+ state : Integer;
+ intensity : Single;
+ pixels, pixel, p : PUint8;
+ width, height : Integer;
+ x, y : Integer;
+ top, bottom, c1, c2 : Uint32;
+ generator : PUint8;
+ color : Integer;
+ area : TPTCArea;
+
+Begin
+ format := Nil;
+ console := Nil;
+ surface := Nil;
+ palette := Nil;
+ area := Nil;
+ Try
+ Try
+ { create format }
+ format := TPTCFormat.Create(8);
+
+ { create console }
+ console := TPTCConsole.Create;
+
+ { open console }
+ console.open('Fire demo', 320, 200, format);
+
+ { create surface }
+ surface := TPTCSurface.Create(320, 208, format);
+
+ { create palette }
+ palette := TPTCPalette.Create;
+
+ { generate palette }
+ generate(palette);
+
+ { set console palette }
+ console.palette(palette);
+
+ { set surface palette }
+ surface.palette(palette);
+
+ { flame data }
+ state := 0;
+ intensity := 0;
+
+ { setup copy area }
+ area := TPTCArea.Create(0, 0, 320, 200);
+
+ { main loop }
+ Repeat
+ { lower flame on keypress }
+ If console.KeyPressed Then
+ state := 2;
+
+ { state machine }
+ Case state Of
+ 0 : Begin
+ { raise flame }
+ intensity += 0.007;
+
+ { maximum flame height }
+ If intensity > 0.8 Then
+ state := 1;
+ End;
+ 1 : Begin
+ { constant flame }
+ End;
+ 2 : Begin
+ { lower flame }
+ intensity := intensity - 0.005;
+
+ { exit program when flame is out }
+ If intensity < 0.01 Then
+ Begin
+ console.close;
+ Exit;
+ End;
+ End;
+ End;
+
+ { lock surface pixels }
+ pixels := surface.lock;
+
+ Try
+ { get surface dimensions }
+ width := surface.width;
+ height := surface.height;
+
+ { flame vertical loop }
+ y := 1;
+ While y < height - 4 Do
+ Begin
+ { current pixel pointer }
+ pixel := pixels + y * width;
+
+ { flame horizontal loop }
+ For x := 0 To width - 1 Do
+ Begin
+ { sum top pixels }
+ p := pixel + (width Shl 1);
+ top := p^;
+ Inc(top, (p - 1)^);
+ Inc(top, (p + 1)^);
+
+ { bottom pixel }
+ bottom := (pixel + (width Shl 2))^;
+
+ { combine pixels }
+ c1 := (top + bottom) Shr 2;
+ If c1 > 1 Then
+ Dec(c1);
+
+ { interpolate }
+ c2 := (c1 + bottom) Shr 1;
+
+ { store pixels }
+ pixel^ := c1;
+ (pixel + width)^ := c2;
+
+ { next pixel }
+ Inc(pixel);
+ End;
+ Inc(y, 2);
+ End;
+
+ { setup flame generator pointer }
+ generator := pixels + width * (height - 4);
+
+ { update flame generator bar }
+ x := 0;
+ While x < width Do
+ Begin
+ { random block color taking intensity into account }
+ color := random(Integer(Trunc(255 * intensity)));
+
+ { write 4x4 color blocks }
+ (generator + 0)^ := color;
+ (generator + 1)^ := color;
+ (generator + 2)^ := color;
+ (generator + 3)^ := color;
+ (generator + width + 0)^ := color;
+ (generator + width + 1)^ := color;
+ (generator + width + 2)^ := color;
+ (generator + width + 3)^ := color;
+ (generator + width * 2 + 0)^ := color;
+ (generator + width * 2 + 1)^ := color;
+ (generator + width * 2 + 2)^ := color;
+ (generator + width * 2 + 3)^ := color;
+ (generator + width * 3 + 0)^ := color;
+ (generator + width * 3 + 1)^ := color;
+ (generator + width * 3 + 2)^ := color;
+ (generator + width * 3 + 3)^ := color;
+
+ { next block }
+ Inc(generator, 4);
+ Inc(x, 4);
+ End;
+
+ Finally
+ { unlock surface }
+ surface.unlock;
+ End;
+
+ { copy surface to console }
+ surface.copy(console, area, area);
+
+ { update console }
+ console.update;
+ Until False;
+
+ Finally
+ console.Free;
+ surface.Free;
+ format.Free;
+ palette.Free;
+ area.Free;
+ End;
+ Except
+ On error : TPTCError Do
+ { report error }
+ error.report;
+ End;
+End.
diff --git a/packages/ptc/examples/flower.pp b/packages/ptc/examples/flower.pp
new file mode 100644
index 0000000000..42d48d3762
--- /dev/null
+++ b/packages/ptc/examples/flower.pp
@@ -0,0 +1,240 @@
+{
+Ported to FPC by Nikolay Nikolov (nickysn@users.sourceforge.net)
+}
+
+{
+ Flower demo for OpenPTC 1.0 C++ API
+ Copyright (c) Scott Buchanan (aka Goblin)
+ This source code is licensed under the GNU GPL
+}
+
+Program Flower;
+
+{$MODE objfpc}
+
+Uses
+ ptc, Math;
+
+Function pack(r, g, b : Uint32) : Uint32;
+
+Begin
+ { pack color integer }
+ pack := (r Shl 16) Or (g Shl 8) Or b;
+End;
+
+Procedure generate_flower(flower : TPTCSurface);
+
+Var
+ data : PUint8;
+ x, y, fx, fy, fx2, fy2 : Integer;
+ TWO_PI : Single;
+
+Begin
+ { lock surface }
+ data := flower.lock;
+
+ Try
+ { surface width and height constants for cleaner code }
+ fx := flower.width;
+ fy := flower.height;
+ fx2 := fx Div 2;
+ fy2 := fy Div 2;
+
+ { useful 2*pi constant }
+ TWO_PI := 2 * PI;
+
+ { generate flower image }
+ For y := 0 To fy - 1 Do
+ For x := 0 To fx - 1 Do
+ data[x + y * fx] := Trunc(1.0 * Cos(18*ArcTan2((y - fy2),(x - fx2))) * 255 / TWO_PI +
+ 0.3 * Sin(15*ArcTan2((y - fy2),(x - fx2))) * 255 / TWO_PI +
+ Sqrt((y - fy2) * (y - fy2) + (x - fx2) * (x - fx2))) And $FF;
+
+ { You might want to move the 1.0 and 0.3 and the 18 and the 15
+ to parameters passed to the generate function...
+ the 1.0 and the 0.3 define the 'height' of the flower, while the
+ 18 and 15 control the number of 'petals' }
+ Finally
+ flower.unlock;
+ End;
+End;
+
+Procedure generate(palette : TPTCPalette);
+
+Var
+ data : PUint32;
+ i, c : Integer;
+
+Begin
+ { lock palette data }
+ data := palette.lock;
+
+ Try
+ { black to yellow }
+ i := 0;
+ c := 0;
+ While i < 64 Do
+ Begin
+ data[i] := pack(c, c, 0);
+ Inc(c, 4);
+ Inc(i);
+ End;
+
+ { yellow to red }
+ c := 0;
+ While i < 128 Do
+ Begin
+ data[i] := pack(255, 255 - c, 0);
+ Inc(c, 4);
+ Inc(i);
+ End;
+
+ { red to white }
+ c := 0;
+ While i < 192 Do
+ Begin
+ data[i] := pack(255, c, c);
+ Inc(c, 4);
+ Inc(i);
+ End;
+
+ { white to black }
+ c := 0;
+ While i < 256 Do
+ Begin
+ data[i] := pack(255 - c, 255 - c, 255 - c);
+ Inc(c, 4);
+ Inc(i);
+ End;
+ Finally
+ { unlock palette }
+ palette.unlock;
+ End;
+End;
+
+Var
+ console : TPTCConsole;
+ format : TPTCFormat;
+ flower_surface : TPTCSurface;
+ surface : TPTCSurface;
+ palette : TPTCPalette;
+ area : TPTCArea;
+ time, delta : Single;
+ scr, map : PUint8;
+ width, height, mapWidth : Integer;
+ xo, yo, xo2, yo2, xo3, yo3 : Single;
+ offset1, offset2, offset3 : Integer;
+ x, y : Integer;
+
+Begin
+ area := Nil;
+ format := Nil;
+ palette := Nil;
+ surface := Nil;
+ flower_surface := Nil;
+ console := Nil;
+ Try
+ Try
+ { create format }
+ format := TPTCFormat.Create(8);
+
+ { create console }
+ console := TPTCConsole.Create;
+
+ { create flower surface }
+ flower_surface := TPTCSurface.Create(640, 400, format);
+
+ { generate flower }
+ generate_flower(flower_surface);
+
+ { open console }
+ console.open('Flower demo', 320, 200, format);
+
+ { create surface }
+ surface := TPTCSurface.Create(320, 200, format);
+
+ { create palette }
+ palette := TPTCPalette.Create;
+
+ { generate palette }
+ generate(palette);
+
+ { set console palette }
+ console.palette(palette);
+
+ { set surface palette }
+ surface.palette(palette);
+
+ { setup copy area }
+ area := TPTCArea.Create(0, 0, 320, 200);
+
+ { time data }
+ time := 0;
+ delta := 0.04;
+
+ { main loop }
+ While Not console.KeyPressed Do
+ Begin
+ { lock surface pixels }
+ scr := surface.lock;
+ Try
+ map := flower_surface.lock;
+ Try
+ { get surface dimensions }
+ width := surface.width;
+ height := surface.height;
+ mapWidth := flower_surface.width;
+
+ xo := (width / 2) + 120 * sin(time * 1.1 + 1.5);
+ yo := (height / 2) + 90 * cos(time * 0.8 + 1.1);
+ offset1 := Trunc(xo) + Trunc(yo) * mapWidth;
+
+ xo2 := (width / 2) + 120 * sin(time * 0.9 + 4.2);
+ yo2 := (height / 2) + 90 * cos(time * 0.7 + 6.9);
+ offset2 := Trunc(xo2) + Trunc(yo2) * mapWidth;
+
+ xo3 := (width / 2) + 120 * sin(time * 0.9 + 3.1);
+ yo3 := (height / 2) + 90 * cos(time * 1.1 + 1.2);
+ offset3 := Trunc(xo3) + Trunc(yo3) * mapWidth;
+
+ { vertical loop }
+ For y := 0 To height - 1 Do
+ { horizontal loop }
+ For x := 0 To width - 1 Do
+ scr[x + y * width] := (map[x + y * mapWidth + offset1] +
+ map[x + y * mapWidth + offset2] +
+ map[x + y * mapWidth + offset3]) And $FF;
+ Finally
+ { unlock surface }
+ flower_surface.unlock;
+ End;
+ Finally
+ { unlock surface }
+ surface.unlock;
+ End;
+
+ { copy surface to console }
+ surface.copy(console, area, area);
+
+ { update console }
+ console.update;
+
+ { update time }
+ time := time + delta;
+ End;
+ Finally
+ If Assigned(console) Then
+ console.close;
+ area.Free;
+ format.Free;
+ palette.Free;
+ surface.Free;
+ flower_surface.Free;
+ console.Free;
+ End;
+ Except
+ On error : TPTCError Do
+ { report error }
+ error.report;
+ End;
+End.
diff --git a/packages/ptc/examples/hicolor.pp b/packages/ptc/examples/hicolor.pp
new file mode 100644
index 0000000000..30f1be3641
--- /dev/null
+++ b/packages/ptc/examples/hicolor.pp
@@ -0,0 +1,94 @@
+{
+Ported to FPC by Nikolay Nikolov (nickysn@users.sourceforge.net)
+}
+
+{
+ HiColor example for OpenPTC 1.0 C++ Implementation
+ Copyright (c) Glenn Fiedler (ptc@gaffer.org)
+ This source code is in the public domain
+}
+
+Program HiColorExample;
+
+{$MODE objfpc}
+
+Uses
+ ptc;
+
+Var
+ console : TPTCConsole;
+ surface : TPTCSurface;
+ format : TPTCFormat;
+ pixels : Pshort16;
+ width, height : Integer;
+ i : Integer;
+ x, y, r, g, b : Integer;
+
+Begin
+ format := Nil;
+ surface := Nil;
+ console := Nil;
+ Try
+ Try
+ { create console }
+ console := TPTCConsole.Create;
+
+ { create format }
+ format := TPTCFormat.Create(16, $F800, $07E0, $001F);
+
+ { open the console }
+ console.open('HiColor example', format);
+
+ { create surface matching console dimensions }
+ surface := TPTCSurface.Create(console.width, console.height, format);
+
+ { loop until a key is pressed }
+ While Not console.KeyPressed Do
+ Begin
+ { lock surface }
+ pixels := surface.lock;
+ Try
+ { get surface dimensions }
+ width := surface.width;
+ height := surface.height;
+
+ { draw random pixels }
+ For i := 1 To 100 Do
+ Begin
+ { get random position }
+ x := Random(width);
+ y := Random(height);
+
+ { get random color }
+ r := Random(256);
+ g := Random(256);
+ b := Random(256);
+
+ { draw color [r,g,b] at position [x,y] }
+ pixels[x + y * width] := ((r And $00F8) Shl 8) Or
+ ((g And $00FC) Shl 3) Or
+ ((b And $00F8) Shr 3);
+ End;
+ Finally
+ { unlock surface }
+ surface.unlock;
+ End;
+
+ { copy to console }
+ surface.copy(console);
+
+ { update console }
+ console.update;
+ End;
+ Finally
+ console.close;
+ console.Free;
+ surface.Free;
+ format.Free;
+ End;
+ Except
+ On error : TPTCError Do
+ { report error }
+ error.report;
+ End;
+End.
diff --git a/packages/ptc/examples/image.pp b/packages/ptc/examples/image.pp
new file mode 100644
index 0000000000..3117032865
--- /dev/null
+++ b/packages/ptc/examples/image.pp
@@ -0,0 +1,106 @@
+{
+Ported to FPC by Nikolay Nikolov (nickysn@users.sourceforge.net)
+}
+
+{
+ Image example for OpenPTC 1.0 C++ Implementation
+ Copyright (c) Glenn Fiedler (ptc@gaffer.org)
+ This source code is in the public domain
+}
+
+Program ImageExample;
+
+{$MODE objfpc}
+
+Uses
+ ptc;
+
+Procedure load(surface : TPTCSurface; filename : String);
+
+Var
+ F : File;
+ width, height : Integer;
+ pixels : PByte;
+ y : Integer;
+ tmp : TPTCFormat;
+ tmp2 : TPTCPalette;
+
+Begin
+ { open image file }
+ ASSign(F, filename);
+ Reset(F, 1);
+
+ { skip header }
+ Seek(F, 18);
+
+ { get surface dimensions }
+ width := surface.width;
+ height := surface.height;
+
+ { allocate image pixels }
+ pixels := GetMem(width * height * 3);
+
+ { read image pixels one line at a time }
+ For y := height - 1 DownTo 0 Do
+ BlockRead(F, pixels[width * y * 3], width * 3);
+
+ { load pixels to surface }
+ tmp := TPTCFormat.Create(24, $00FF0000, $0000FF00, $000000FF);
+ tmp2 := TPTCPalette.Create;
+ surface.load(pixels, width, height, width * 3, tmp, tmp2);
+ tmp2.Free;
+ tmp.Free;
+
+ { free image pixels }
+ FreeMem(pixels);
+End;
+
+Var
+ console : TPTCConsole;
+ format : TPTCFormat;
+ surface : TPTCSurface;
+
+Begin
+ Try
+ { create console }
+ console := TPTCConsole.Create;
+
+ { create format }
+ format := TPTCFormat.Create(32, $00FF0000, $0000FF00, $000000FF);
+
+ Try
+ { try to open the console matching the image resolution }
+ console.open('Image example', 320, 200, format);
+ Except
+ On TPTCError Do
+ { fallback to the default resolution }
+ console.open('Image example', format);
+ End;
+
+ { create surface }
+ surface := TPTCSurface.Create(320, 200, format);
+ format.Free;
+
+ { load image to surface }
+ load(surface, 'image.tga');
+
+ { copy surface to console }
+ surface.copy(console);
+
+ { update console }
+ console.update;
+
+ { read key }
+ console.ReadKey;
+
+ { close console }
+ console.close;
+
+ console.Free;
+ surface.Free;
+ Except
+ On error : TPTCError Do
+ { report error }
+ error.report;
+ End;
+End.
diff --git a/packages/ptc/examples/image.tga b/packages/ptc/examples/image.tga
new file mode 100644
index 0000000000..3ae321df8b
--- /dev/null
+++ b/packages/ptc/examples/image.tga
Binary files differ
diff --git a/packages/ptc/examples/keyboard.pp b/packages/ptc/examples/keyboard.pp
new file mode 100644
index 0000000000..7396e90336
--- /dev/null
+++ b/packages/ptc/examples/keyboard.pp
@@ -0,0 +1,116 @@
+{
+Ported to FPC by Nikolay Nikolov (nickysn@users.sourceforge.net)
+}
+
+{
+ Keyboard example for OpenPTC 1.0 C++ Implementation
+ Copyright (c) Glenn Fiedler (ptc@gaffer.org)
+ This source code is in the public domain
+}
+
+Program KeyboardExample;
+
+{$MODE objfpc}
+
+Uses
+ ptc;
+
+Var
+ console : TPTCConsole;
+ surface : TPTCSurface;
+ format : TPTCFormat;
+ color : TPTCColor;
+ key : TPTCKey;
+ area : TPTCArea;
+ x, y : Integer;
+ size : Integer;
+ delta : Integer;
+
+Begin
+ key := Nil;
+ color := Nil;
+ format := Nil;
+ surface := Nil;
+ console := Nil;
+ Try
+ Try
+ { create key }
+ key := TPTCKey.Create;
+
+ { create console }
+ console := TPTCConsole.Create;
+
+ { create format }
+ format := TPTCFormat.Create(32, $00FF0000, $0000FF00, $000000FF);
+
+ { open the console }
+ console.open('Keyboard example', format);
+
+ { create surface matching console dimensions }
+ surface := TPTCSurface.Create(console.width, console.height, format);
+
+ { setup cursor data }
+ x := surface.width Div 2;
+ y := surface.height Div 2;
+ size := surface.width Div 10;
+ color := TPTCColor.Create(1, 1, 1);
+
+ { main loop }
+ Repeat
+ { check for key press }
+ If console.KeyPressed Then
+ Begin
+ { read console key press }
+ console.ReadKey(key);
+
+ { shift modifier }
+ If key.shift Then
+ { move fast }
+ delta := 10
+ Else
+ { move slow }
+ delta := 1;
+
+ { handle cursor keys }
+ Case key.code Of
+ PTCKEY_LEFT : Dec(x, delta);
+ PTCKEY_RIGHT : Inc(x, delta);
+ PTCKEY_UP : Dec(y, delta);
+ PTCKEY_DOWN : Inc(y, delta);
+ { exit when escape is pressed }
+ PTCKEY_ESCAPE : Break;
+ End;
+ End;
+
+ { clear surface }
+ surface.clear;
+
+ { setup cursor area }
+ area := TPTCArea.Create(x - size, y - size, x + size, y + size);
+ Try
+ { draw cursor as a quad }
+ surface.clear(color, area);
+ Finally
+ area.Free;
+ End;
+
+ { copy to console }
+ surface.copy(console);
+
+ { update console }
+ console.update;
+ Until False;
+ Finally
+ color.Free;
+ console.close;
+ console.Free;
+ surface.Free;
+ key.Free;
+ format.Free;
+ End;
+ Except
+ On error : TPTCError Do
+ { report error }
+ error.report;
+ End;
+End.
diff --git a/packages/ptc/examples/keybrd2.pp b/packages/ptc/examples/keybrd2.pp
new file mode 100644
index 0000000000..53ed8e368f
--- /dev/null
+++ b/packages/ptc/examples/keybrd2.pp
@@ -0,0 +1,120 @@
+Program KeyboardExample2;
+
+{$MODE objfpc}
+
+Uses
+ ptc;
+
+Var
+ console : TPTCConsole;
+ surface : TPTCSurface;
+ format : TPTCFormat;
+ color : TPTCColor;
+ timer : TPTCTimer;
+ key : TPTCKey;
+ area : TPTCArea;
+ x, y, delta : Real;
+ left, right, up, down : Boolean;
+ size : Integer;
+ Done : Boolean;
+
+Begin
+ left := False;
+ right := False;
+ up := False;
+ down := False;
+ Try
+ Try
+ { create key }
+ key := TPTCKey.Create;
+
+ { create console }
+ console := TPTCConsole.Create;
+
+ { enable key release events }
+ console.KeyReleaseEnabled := True;
+
+ { create format }
+ format := TPTCFormat.Create(32, $00FF0000, $0000FF00, $000000FF);
+
+ { open the console }
+ console.open('Keyboard example 2', format);
+
+ { create timer }
+ timer := TPTCTimer.Create;
+
+ { create surface matching console dimensions }
+ surface := TPTCSurface.Create(console.width, console.height, format);
+
+ { setup cursor data }
+ x := surface.width Div 2;
+ y := surface.height Div 2;
+ size := surface.width Div 10;
+ color := TPTCColor.Create(1, 1, 1);
+
+ { start timer }
+ timer.start;
+
+ { main loop }
+ Done := False;
+ Repeat
+ { check for key press/release }
+ While console.KeyPressed Do
+ Begin
+ console.ReadKey(key);
+ Case key.code Of
+ PTCKEY_LEFT : left := key.press;
+ PTCKEY_RIGHT : right := key.press;
+ PTCKEY_UP : up := key.press;
+ PTCKEY_DOWN : down := key.press;
+ PTCKEY_ESCAPE : Begin
+ Done := True;
+ Break;
+ End;
+ End;
+ End;
+
+ { move square }
+ delta := timer.delta*100;
+ If left Then
+ x -= delta;
+ If right Then
+ x += delta;
+ If up Then
+ y -= delta;
+ If down Then
+ y += delta;
+
+ { clear surface }
+ surface.clear;
+
+ { setup cursor area }
+ area := TPTCArea.Create(Trunc(x) - size, Trunc(y) - size, Trunc(x) + size, Trunc(y) + size);
+ Try
+ { draw cursor as a quad }
+ surface.clear(color, area);
+ Finally
+ area.Free;
+ End;
+
+ { copy to console }
+ surface.copy(console);
+
+ { update console }
+ console.update;
+ Until Done;
+ Finally
+ color.Free;
+ console.close;
+ console.Free;
+ surface.Free;
+ key.Free;
+ timer.Free;
+ format.Free;
+ End;
+ Except
+ On error : TPTCError Do
+ { report error }
+ error.report;
+ End;
+End.
diff --git a/packages/ptc/examples/land.pp b/packages/ptc/examples/land.pp
new file mode 100644
index 0000000000..930828c108
--- /dev/null
+++ b/packages/ptc/examples/land.pp
@@ -0,0 +1,402 @@
+{
+Ported to FPC by Nikolay Nikolov (nickysn@users.sourceforge.net)
+}
+
+{
+ Land demo for OpenPTC 1.0 C++ API
+
+ Based on Heightmap example from Hornet (RIP)
+ PTC version Copyright (c) 1998 Marcus Fletcher (cus@commsat.demon.co.uk)
+
+ Updated to OpenPTC 1.0 by Glenn Fiedler (ptc@gaffer.org)
+
+ Cursor keys to move, <Pause> to brake and <Esc> to quit
+}
+
+Program Land;
+
+{$MODE objfpc}
+
+Uses
+ ptc;
+
+Const
+ SCREENWIDTH = 320;
+ SCREENHEIGHT = 200;
+
+ FOV : Integer = 256; { half of the xy field of view (This is based on the 0-2048 convention) }
+
+Var
+ HMap : Array[0..256*256 - 1] Of Uint8; { Height field }
+ CMap : Array[0..256*256 - 1] Of Uint8; { Color map }
+
+ lasty, { Last pixel drawn on a given column }
+ lastc : Array[0..SCREENWIDTH - 1] Of Integer; { Color of last pixel on a column }
+ CosT, SinT : Array[0..2047] Of Integer; { Cosine and Sine tables }
+
+{ Reduces a value to 0..255 (used in height field computation) }
+Function Clamp(x : Integer) : Integer;
+
+Begin
+ If x < 0 Then
+ Clamp := 0
+ Else
+ If x > 255 Then
+ Clamp := 255
+ Else
+ Clamp := x;
+End;
+
+{ Heightfield and colormap computation }
+Procedure ComputeMap;
+
+Var
+ p, i, j, k, k2, p2, a, b, c, d : Integer;
+
+Begin
+ { Start from a plasma clouds fractal }
+ HMap[0] := 128;
+ p := 256;
+ While p > 1 Do
+ Begin
+ p2 := p Shr 1;
+ k := p * 8 + 20;
+ k2 := k Shr 1;
+ i := 0;
+ While i < 256 Do
+ Begin
+ j := 0;
+ While j < 256 Do
+ Begin
+ a := HMap[(i Shl 8) + j];
+ b := HMap[(((i + p) And 255) Shl 8) + j];
+ c := HMap[(i Shl 8) + ((j + p) And 255)];
+ d := HMap[(((i + p) And 255) Shl 8) + ((j + p) And 255)];
+
+ HMap[(i Shl 8) + ((j + p2) And 255)] :=
+ Clamp(((a + c) Shr 1) + (Random(k) - k2));
+ HMap[(((i + p2) And 255) Shl 8) + ((j + p2) And 255)] :=
+ Clamp(((a + b + c + d) Shr 2) + (Random(k) - k2));
+ HMap[(((i + p2) And 255) Shl 8) + j] :=
+ Clamp(((a + b) Shr 1) + (Random(k) - k2));
+ Inc(j, p);
+ End;
+ Inc(i, p);
+ End;
+ p := p2;
+ End;
+
+ { Smoothing }
+ For k := 0 To 2 Do
+ Begin
+ i := 0;
+ While i < 256*256 Do
+ Begin
+ For j := 0 To 255 Do
+ HMap[i + j] := (HMap[((i + 256) And $FF00) + j] +
+ HMap[i + ((j + 1) And $FF)] +
+ HMap[((i - 256) And $FF00) + j] +
+ HMap[i + ((j - 1) And $FF)]) Shr 2;
+ Inc(i, 256);
+ End;
+ End;
+
+ { Color computation (derivative of the height field) }
+ i := 0;
+ While i < 256*256 Do
+ Begin
+ For j := 0 To 255 Do
+ Begin
+ k := 128 + (HMap[((i + 256) And $FF00) + ((j + 1) And 255)] - HMap[i + j])*4;
+ If k < 0 Then
+ k := 0;
+ If k > 255 Then
+ k := 255;
+ CMap[i + j] := k;
+ End;
+ Inc(i, 256);
+ End;
+End;
+
+{ Calculate the lookup tables }
+Procedure InitTables;
+
+Var
+ a : Integer;
+ result : Single;
+
+Begin
+ For a := 0 To 2047 Do
+ Begin
+ { Precalculate cosine }
+ result := cos(a * PI / 1024) * 256;
+ CosT[a] := Trunc(result);
+
+ { and sine }
+ result := sin(a * PI / 1024) * 256;
+ SinT[a] := Trunc(result);
+ End;
+End;
+
+{
+ Draw a "section" of the landscape; x0,y0 and x1,y1 and the xy coordinates
+ on the height field, hy is the viewpoint height, s is the scaling factor
+ for the distance. x0,y0,x1,y1 are 16.16 fixed point numbers and the
+ scaling factor is a 16.8 fixed point value.
+}
+Procedure Line(x0, y0, x1, y1, hy, s : Integer; surface_buffer : PUint32; fadeout : Integer);
+
+Var
+ sx, sy, i, a, b, u0, u1, v0, v1, h0, h1, h2, h3, h, c, y : Integer;
+ coord_x, coord_y, sc, cc, currentColor : Integer;
+ pixel : PUint32;
+
+Begin
+ { Compute xy speed }
+ sx := (x1 - x0) Div SCREENWIDTH;
+ sy := (y1 - y0) Div SCREENWIDTH;
+
+ For i := 0 To SCREENWIDTH - 1 Do
+ Begin
+ { Compute the xy coordinates; a and b will be the position inside the }
+ { single map cell (0..255). }
+ a := (x0 Shr 8) And $FF;
+ b := (y0 Shr 8) And $FF;
+
+ u0 := (x0 Shr 16) And $FF;
+ u1 := (u0 + 1) And $FF;
+ v0 := (y0 Shr 8) And $FF00;
+ v1 := (v0 + 256) And $FF00;
+
+ { Fetch the height at the four corners of the square the point is in }
+ h0 := HMap[u0 + v0];
+ h1 := HMap[u1 + v0];
+ h2 := HMap[u0 + v1];
+ h3 := HMap[u1 + v1];
+
+ { Compute the height using bilinear interpolation }
+ h0 := (h0 Shl 8) + a * (h1 - h0);
+ h2 := (h2 Shl 8) + a * (h3 - h2);
+ h := ((h0 Shl 8) + b * (h2 - h0)) Shr 16;
+
+ { Fetch the color at the centre of the square the point is in }
+ h0 := CMap[u0 + v0];
+ h1 := CMap[u1 + v0];
+ h2 := CMap[u0 + v1];
+ h3 := CMap[u1 + v1];
+
+ { Compute the color using bilinear interpolation (in 16.16) }
+ h0 := (h0 Shl 8) + a * (h1 - h0);
+ h2 := (h2 Shl 8) + a * (h3 - h2);
+ c := ((h0 Shl 8) + b * (h2 - h0));
+
+ { Compute screen height using the scaling factor }
+ y := (((h - hy) * s) Shr 11) + (SCREENHEIGHT Shr 1);
+
+ { Draw the column }
+ a := lasty[i];
+ If y < a Then
+ Begin
+ coord_x := i;
+ coord_y := a;
+ If lastc[i] = -1 Then
+ lastc[i] := c;
+
+ sc := (c - lastc[i]) Div (a - y);
+ cc := lastc[i];
+
+ If a > (SCREENHEIGHT - 1) Then
+ Begin
+ Dec(coord_y, a - (SCREENHEIGHT - 1));
+ a := SCREENHEIGHT - 1;
+ End;
+ If y < 0 Then
+ y := 0;
+
+ While y < a Do
+ Begin
+ currentColor := cc Shr 18;
+ pixel := surface_buffer + (coord_y * SCREENWIDTH) + coord_x;
+ pixel^ := ((currentColor Shl 2) * (150 - fadeout) Div 150) Shl 8;
+ Inc(cc, sc);
+ Dec(coord_y);
+ Dec(a);
+ End;
+ lasty[i] := y;
+ End;
+ lastc[i] := c;
+
+ { Advance to next xy position }
+ Inc(x0, sx); Inc(y0, sy);
+ End;
+End;
+
+{ Draw the view from the point x0,y0 (16.16) looking at angle a }
+Procedure View(x0, y0, angle, height : Integer; surface_buffer : PUint32);
+
+Var
+ d, u0, a, v0, u1, v1, h0, h1, h2, h3 : Integer;
+
+Begin
+ { Initialize last-y and last-color arrays }
+ For d := 0 To SCREENWIDTH - 1 Do
+ Begin
+ lasty[d] := SCREENHEIGHT;
+ lastc[d] := -1;
+ End;
+
+ { Compute the xy coordinates; a and b will be the position inside the }
+ { single map cell (0..255). }
+ u0 := (x0 Shr 16) And $FF;
+ a := (x0 Shr 8) And $FF;
+ v0 := (y0 Shr 8) And $FF00;
+ u1 := (u0 + 1) And $FF;
+ v1 := (v0 + 256) And $FF00;
+
+ { Fetch the height at the four corners of the square the point is in }
+ h0 := HMap[u0 + v0];
+ h1 := HMap[u1 + v0];
+ h2 := HMap[u0 + v1];
+ h3 := HMap[u1 + v1];
+
+ { Compute the height using bilinear interpolation }
+ h0 := (h0 Shl 8) + a * (h1 - h0);
+ h2 := (h2 Shl 8) + a * (h3 - h2);
+
+ { Draw the landscape from near to far without overdraw }
+ d := 0;
+ While d < 150 Do
+ Begin
+ Line(x0 + (d Shl 8)*CosT[(angle - FOV) And $7FF],
+ y0 + (d Shl 8)*SinT[(angle - FOV) And $7FF],
+ x0 + (d Shl 8)*CosT[(angle + FOV) And $7FF],
+ y0 + (d Shl 8)*SinT[(angle + FOV) And $7FF],
+ height, (100 Shl 8) Div (d + 1),
+ surface_buffer,
+ d);
+ Inc(d, 1 + (d Shr 6));
+ End;
+End;
+
+Var
+ format : TPTCFormat;
+ console : TPTCConsole;
+ surface : TPTCSurface;
+ timer : TPTCTimer;
+ key : TPTCKeyEvent;
+ pixels : PUint32;
+ Done : Boolean;
+
+ x0, y0 : Integer;
+ height : Integer;
+ angle, deltaAngle, deltaSpeed, CurrentSpeed, scale, delta : Double;
+ index : Integer;
+
+Begin
+ Done := False;
+ format := Nil;
+ console := Nil;
+ surface := Nil;
+ timer := Nil;
+ key := Nil;
+ Try
+ Try
+ key := TPTCKeyEvent.Create;
+ format := TPTCFormat.Create(32, $00FF0000, $0000FF00, $000000FF);
+ console := TPTCConsole.Create;
+ console.open('Land demo', SCREENWIDTH, SCREENHEIGHT, format);
+ surface := TPTCSurface.Create(SCREENWIDTH, SCREENHEIGHT, format);
+
+ { Compute the height map }
+ ComputeMap;
+ InitTables;
+
+ x0 := 0;
+ y0 := 0;
+
+ height := -200;
+ angle := 0;
+ deltaAngle := 0;
+ deltaSpeed := 4096;
+ CurrentSpeed := deltaSpeed * 10;
+
+ { time scaling constant }
+ scale := 20;
+
+ { create timer }
+ timer := TPTCTimer.Create;
+
+ { start timer }
+ timer.start;
+
+ { main loop }
+ Repeat
+ { get time delta between frames }
+ delta := timer.delta;
+
+ { clear surface }
+ surface.clear;
+
+ { lock surface pixels }
+ pixels := surface.lock;
+ Try
+ { draw current landscape view }
+ View(x0, y0, Trunc(angle), height, pixels);
+ Finally
+ { unlock surface }
+ surface.unlock;
+ End;
+
+ { copy surface to console }
+ surface.copy(console);
+
+ { update console }
+ console.update;
+
+ { check key press }
+ While console.KeyPressed Do
+ Begin
+ { read key press }
+ console.ReadKey(key);
+
+ { handle key press }
+ Case key.code Of
+ { increase speed }
+ PTCKEY_UP : CurrentSpeed += deltaSpeed * delta * scale;
+ { decrease speed }
+ PTCKEY_DOWN : CurrentSpeed -= deltaSpeed * delta * scale;
+ { turn to the left }
+ PTCKEY_LEFT : deltaAngle -= 1;
+ { turn to the right }
+ PTCKEY_RIGHT : deltaAngle += 1;
+ PTCKEY_SPACE : Begin
+ { stop moving }
+ CurrentSpeed := 0;
+ deltaAngle := 0;
+ End;
+ { exit }
+ PTCKEY_ESCAPE : Done := True;
+ End;
+ End;
+
+ { Update position/angle }
+ angle += deltaAngle * delta * scale;
+
+ index := Trunc(angle) And $7FF;
+ Inc(x0, Trunc(CurrentSpeed * CosT[index]) Div 256);
+ Inc(y0, Trunc(CurrentSpeed * SinT[index]) Div 256);
+ Until Done;
+ Finally
+ console.close;
+ console.Free;
+ surface.Free;
+ timer.Free;
+ format.Free;
+ key.Free;
+ End;
+ Except
+ On error : TPTCError Do
+ { report error }
+ error.report;
+ End;
+End.
diff --git a/packages/ptc/examples/lights.pp b/packages/ptc/examples/lights.pp
new file mode 100644
index 0000000000..74acca956b
--- /dev/null
+++ b/packages/ptc/examples/lights.pp
@@ -0,0 +1,290 @@
+{
+Ported to FPC by Nikolay Nikolov (nickysn@users.sourceforge.net)
+}
+
+{
+ Lights demo for OpenPTC 1.0 C++ API
+ Copyright (c) Glenn Fiedler (ptc@gaffer.org)
+ This source code is licensed under the GNU GPL
+}
+
+Program Lights;
+
+{$MODE objfpc}
+
+Uses
+ ptc;
+
+Var
+ { distance lookup table }
+ distance_table : Array[0..299, 0..511] Of DWord; { note: 16.16 fixed }
+
+{ intensity calculation }
+Function CalcIntensity(dx, dy : Integer; i : DWord) : DWord;{ Inline;}
+
+Begin
+ { lookup intensity at [dx,dy] }
+ CalcIntensity := i * distance_table[dy, dx];
+End;
+
+Var
+ console : TPTCConsole;
+ surface : TPTCSurface;
+ format : TPTCFormat;
+ palette : TPTCPalette;
+ dx, dy : Integer;
+ divisor : Single;
+ data : PUint32;
+ pixels, line : PUint8;
+ width : Integer;
+ i : Integer;
+ x, y, x1, y1, x2, y2, x3, y3, x4, y4 : Integer;
+ cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4 : Single;
+ dx1, dy1, dx2, dy2, dx3, dy3, dx4, dy4 : Single;
+ _dx1, _dx2, _dx3, _dx4 : Integer;
+ _dy1, _dy2, _dy3, _dy4 : Integer;
+ ix1, ix2, ix3, ix4 : Integer;
+ i1, i2, i3, i4 : DWord;
+ length : Integer;
+ move_t, move_dt, move_ddt : Single;
+ flash_t, flash_dt, flash_ddt : Single;
+ intensity : DWord;
+ max_intensity, max_intensity_inc : Single;
+
+Begin
+ console := Nil;
+ format := Nil;
+ surface := Nil;
+ palette := Nil;
+ Try
+ Try
+ { create console }
+ console := TPTCConsole.Create;
+
+ format := TPTCFormat.Create(8);
+
+ { open console }
+ console.open('Lights demo', 320, 200, format);
+
+ { create surface }
+ surface := TPTCSurface.Create(320, 200, format);
+
+ { setup intensity table }
+ For dy := 0 To 199 Do
+ For dx := 0 To 511 Do
+ Begin
+ divisor := sqrt((dx * dx) + (dy * dy));
+ If divisor < 0.3 Then
+ divisor := 0.3;
+ distance_table[dy, dx] := Trunc(65535 / divisor);
+ End;
+
+ { create palette }
+ palette := TPTCPalette.Create;
+
+ { generate greyscale palette }
+ data := palette.lock;
+ Try
+ For i := 0 To 255 Do
+ data[i] := (i Shl 16) Or (i Shl 8) Or i;
+ Finally
+ palette.unlock;
+ End;
+
+ { set console palette }
+ console.palette(palette);
+
+ { set surface palette }
+ surface.palette(palette);
+
+ { data }
+ cx1 := 60;
+ cy1 := 110;
+ cx2 := 100;
+ cy2 := 80;
+ cx3 := 250;
+ cy3 := 110;
+ cx4 := 200;
+ cy4 := 90;
+ dx1 := 0;
+ dy1 := 0;
+ dx2 := 0;
+ dy2 := 0;
+ dx3 := 0;
+ dy3 := 0;
+ dx4 := 0;
+ dy4 := 0;
+ i1 := 0;
+ i2 := 0;
+ i3 := 0;
+ i4 := 0;
+
+ { time data }
+ move_t := 0.3;
+ move_dt := 0.1;
+ move_ddt := 0.0006;
+ flash_t := 0.1;
+ flash_dt := 0.0;
+ flash_ddt := 0.0004;
+
+ { control data }
+ max_intensity := 30;
+ max_intensity_inc := 0.2;
+
+ { main loop }
+ While Not console.KeyPressed Do
+ Begin
+ { source positions }
+ x1 := Trunc(cx1 + dx1);
+ y1 := Trunc(cy1 + dy1);
+ x2 := Trunc(cx2 + dx2);
+ y2 := Trunc(cy2 + dy2);
+ x3 := Trunc(cx3 + dx3);
+ y3 := Trunc(cy3 + dy3);
+ x4 := Trunc(cx4 + dx4);
+ y4 := Trunc(cy4 + dy4);
+
+ { lock surface }
+ pixels := surface.lock;
+ Try
+ { get surface dimensions }
+ width := surface.width;
+
+ { line loop }
+ For y := 0 To 199 Do
+ Begin
+ { calcalate pointer to start of line }
+ line := pixels + y * width;
+
+ { get y deltas }
+ _dy1 := abs(y - y1);
+ _dy2 := abs(y - y2);
+ _dy3 := abs(y - y3);
+ _dy4 := abs(y - y4);
+
+ { setup x }
+ x := 0;
+
+ { line loop }
+ While x < width Do
+ Begin
+ { get x deltas }
+ _dx1 := abs(x1 - x);
+ _dx2 := abs(x2 - x);
+ _dx3 := abs(x3 - x);
+ _dx4 := abs(x4 - x);
+
+ { get increments }
+ ix1 := 1;
+ ix2 := 1;
+ ix3 := 1;
+ ix4 := 1;
+ If x1 > x Then
+ ix1 := -1;
+ If x2 > x Then
+ ix2 := -1;
+ If x3 > x Then
+ ix3 := -1;
+ If x4 > x Then
+ ix4 := -1;
+
+ { set span length to min delta }
+ length := width - x;
+ If (x1 > x) And (_dx1 < length) Then
+ length := _dx1;
+ If (x2 > x) And (_dx2 < length) Then
+ length := _dx2;
+ If (x3 > x) And (_dx3 < length) Then
+ length := _dx3;
+ If (x4 > x) And (_dx4 < length) Then
+ length := _dx4;
+
+ { pixel loop }
+ While length > 0 Do
+ Begin
+ Dec(length);
+ { calc intensities }
+ intensity := CalcIntensity(_dx1, _dy1, i1);
+ Inc(intensity, CalcIntensity(_dx2, _dy2, i2));
+ Inc(intensity, CalcIntensity(_dx3, _dy3, i3));
+ Inc(intensity, CalcIntensity(_dx4, _dy4, i4));
+ intensity := intensity Shr 16;
+ If intensity > 255 Then
+ intensity := 255;
+
+ { update deltas }
+ Inc(_dx1, ix1);
+ Inc(_dx2, ix2);
+ Inc(_dx3, ix3);
+ Inc(_dx4, ix4);
+
+ { store the pixel }
+ line[x] := intensity;
+ Inc(x);
+ End;
+ End;
+ End;
+ Finally
+ { unlock surface }
+ surface.unlock;
+ End;
+
+ { move the lights around }
+ dx1 := 50 * sin((move_t + 0.0) * 0.10);
+ dy1 := 80 * sin((move_t + 0.6) * 0.14);
+ dx2 := 100 * sin((move_t + 0.1) * 0.10);
+ dy2 := 30 * sin((move_t - 0.4) * 0.30);
+ dx3 := 39 * sin((move_t + 9.9) * 0.20);
+ dy3 := 50 * sin((move_t + 0.4) * 0.30);
+ dx4 := 70 * sin((move_t - 0.3) * 0.25);
+ dy4 := 40 * sin((move_t - 0.1) * 0.31);
+
+ { flash intensity }
+ i1 := Trunc(max_intensity * (sin((flash_t + 0.000) * 1.000) + 1));
+ i2 := Trunc(max_intensity * (sin((flash_t + 2.199) * 0.781) + 1));
+ i3 := Trunc(max_intensity * (sin((flash_t - 1.450) * 1.123) + 1));
+ i4 := Trunc(max_intensity * (sin((flash_t + 0.000) * 0.500) + 1));
+
+ { update time }
+ move_t := move_t + move_dt;
+ move_dt := move_dt + move_ddt;
+ flash_t := flash_t + flash_dt;
+ flash_dt := flash_dt + flash_ddt;
+
+ { reset on big flash... }
+ If (move_t > 600) And (i1 > 10000) And (i2 > 10000) And
+ (i3 > 10000) And (i4 > 10000) Then
+ Begin
+ move_t := 0.3;
+ move_dt := 0.1;
+ move_ddt := 0.0006;
+ flash_t := 0.1;
+ flash_dt := 0.0;
+ flash_ddt := 0.0004;
+ max_intensity := 0.0;
+ max_intensity_inc := 0.2;
+ End;
+
+ { update intensity }
+ max_intensity := max_intensity + max_intensity_inc;
+ max_intensity_inc := max_intensity_inc + 0.008;
+
+ { copy surface to console }
+ surface.copy(console);
+
+ { update console }
+ console.update;
+ End;
+ Finally
+ console.close;
+ surface.Free;
+ console.Free;
+ palette.Free;
+ format.Free;
+ End;
+ Except
+ On error : TPTCError Do
+ { report error }
+ error.report;
+ End;
+End.
diff --git a/packages/ptc/examples/modes.pp b/packages/ptc/examples/modes.pp
new file mode 100644
index 0000000000..bd8ee551ba
--- /dev/null
+++ b/packages/ptc/examples/modes.pp
@@ -0,0 +1,100 @@
+{
+Ported to FPC by Nikolay Nikolov (nickysn@users.sourceforge.net)
+}
+
+{
+ Modes example for OpenPTC 1.0 C++ Implementation
+ Copyright (c) Glenn Fiedler (ptc@gaffer.org)
+ This source code is in the public domain
+}
+
+Program ModesExample;
+
+{$MODE objfpc}
+
+Uses
+ ptc;
+
+Procedure print(Const format : TPTCFormat);
+
+Begin
+ { check format type }
+ If format.direct Then
+ { check alpha }
+ If format.a = 0 Then
+ { direct color format without alpha }
+ Write('Format(', format.bits:2, ',$', HexStr(format.r, 8), ',$', HexStr(format.g, 8), ',$', HexStr(format.b, 8), ')')
+ Else
+ { direct color format with alpha }
+ Write('Format(', format.bits:2, ',$', HexStr(format.r, 8), ',$', HexStr(format.g, 8), ',$', HexStr(format.b, 8), ',$', HexStr(format.a, 8), ')')
+ Else
+ { indexed color format }
+ Write('Format(', format.bits:2, ')');
+End;
+
+Procedure print(Const mode : TPTCMode);
+
+Begin
+ { print mode width and height }
+ Write(' ', mode.width:4, ' x ', mode.height);
+ If mode.height < 1000 Then
+ Write(' ');
+ If mode.height < 100 Then
+ Write(' ');
+ If mode.height < 10 Then
+ Write(' ');
+ Write(' x ');
+
+ { print mode format }
+ print(mode.format);
+
+ { newline }
+ Writeln;
+End;
+
+Var
+ console : TPTCConsole;
+ modes : PPTCMode;
+ index : Integer;
+
+Begin
+ console := Nil;
+ Try
+ Try
+ { create console }
+ console := TPTCConsole.Create;
+
+ { get list of console modes }
+ modes := console.modes;
+
+ { check for empty list }
+ If Not modes[0].valid Then
+ { the console mode list was empty }
+ Writeln('[console mode list is not available]')
+ Else
+ Begin
+ { print mode list header }
+ Writeln('[console modes]');
+
+ { mode index }
+ index := 0;
+
+ { iterate through all modes }
+ While modes[index].valid Do
+ Begin
+ { print mode }
+ print(modes[index]);
+
+ { next mode }
+ Inc(index);
+ End;
+ End;
+ Finally
+ console.Free;
+ End;
+ Except
+ On error : TPTCError Do
+ { report error }
+ error.report;
+ End;
+End.
diff --git a/packages/ptc/examples/mojo.pp b/packages/ptc/examples/mojo.pp
new file mode 100644
index 0000000000..a6fcc285a3
--- /dev/null
+++ b/packages/ptc/examples/mojo.pp
@@ -0,0 +1,815 @@
+{
+Ported to FPC by Nikolay Nikolov (nickysn@users.sourceforge.net)
+}
+
+{
+Mojo demo for OpenPTC 1.0 C++ API
+Coded by Alex Evans and adapted to OpenPTC 1.0 by Glenn Fiedler
+
+nasty code by alex "statix" evans for ptc. (c) copyright alex evans 1998
+time... 02.00 am on 13/1/98.
+have fun
+it's my take on some classic light mask effect
+it's raytracing through properly modelled fog with occlusion, multiple
+shadow rays cast back to the light for each pixel ray, and erm, its
+s l o w... but it looks nice don't it?
+
+oh and fresnel fall off... or something
+
+UNTESTED! ok?
+
+define inv for interesting fx (not)
+}
+
+Program Mojo;
+
+{$MODE objfpc}
+
+Uses
+ ptc, SysUtils;
+
+{ $DEFINE INV}
+
+Const
+ SC = 12;
+ MINSEGSIZE = 2.5;
+ NSEG = 5;
+ frandtab_seed : Uint16 = 54;
+
+Var
+ MaskMap : PUint8;
+ frandtab : Array[0..65535] Of Uint16;
+
+Type
+ FVector = Object
+{ Case Boolean Of
+ False : (X, Y, Z : Single);
+ True : (R, G, B : Single);}
+ X, Y, Z : Single;
+
+ Constructor Init;
+ Constructor Init(_x, _y, _z : Single);
+
+ Function Magnitude : Single;
+ Function MagnitudeSq : Single;
+ Procedure Normalise;
+ End;
+ FMatrix = Object
+ Row : Array[0..2] Of FVector;
+ Constructor Init;
+ Constructor Init(a, b, c : FVector);
+ Function Column0 : FVector;
+ Function Column1 : FVector;
+ Function Column2 : FVector;
+ Procedure MakeXRot(theta : Single);
+ Procedure MakeYRot(theta : Single);
+ Procedure MakeZRot(theta : Single);
+ Procedure MakeID;
+ Function Transpose : FMatrix;
+ Procedure TransposeInPlace;
+ Procedure Normalise;
+ End;
+ PRay = ^TRay;
+ TRay = Object
+ mPosn : FVector;
+ mDir : FVector;
+ Constructor Init(Const p, d : FVector);
+ End;
+ VLight = Class(TObject)
+ mAng : Single;
+ mPosn : FVector;
+ mTarget : FVector;
+ mAxis : FMatrix;
+ mCol : FVector;
+
+ p, p2, _d : FVector; { temp space }
+
+ Constructor Create(Const col : FVector);
+ Procedure Move(Const q : FVector);
+ Procedure MoveT(Const q : FVector);
+ Procedure Update;
+ Function Light(Const ray : TRay) : FVector;
+ Function CalcLight(t : Single) : Single;
+ End;
+
+Constructor FVector.Init;
+
+Begin
+End;
+
+Constructor FVector.Init(_x, _y, _z : Single);
+
+Begin
+ X := _x;
+ Y := _y;
+ Z := _z;
+End;
+
+Function FVector.Magnitude : Single;
+
+Begin
+ Magnitude := Sqrt(Sqr(X) + Sqr(Y) + Sqr(Z));
+End;
+
+Function FVector.MagnitudeSq : Single;
+
+Begin
+ MagnitudeSq := Sqr(X) + Sqr(Y) + Sqr(Z);
+End;
+
+Procedure FVector.Normalise;
+
+Var
+ l : Single;
+
+Begin
+ l := 1 / Magnitude;
+ X *= l;
+ Y *= l;
+ Z *= l;
+End;
+
+Operator * (a, b : FVector) res : Single;
+
+Begin
+ res := a.X * b.X + a.Y * b.Y + a.Z * b.Z;
+End;
+
+Operator * (a : FVector; b : Single) res : FVector;
+
+Begin
+ res.X := a.X * b;
+ res.Y := a.Y * b;
+ res.Z := a.Z * b;
+End;
+
+Operator + (a, b : FVector) res : FVector;
+
+Begin
+ res.X := a.X + b.X;
+ res.Y := a.Y + b.Y;
+ res.Z := a.Z + b.Z;
+End;
+
+Operator - (a, b : FVector) res : FVector;
+
+Begin
+ res.X := a.X - b.X;
+ res.Y := a.Y - b.Y;
+ res.Z := a.Z - b.Z;
+End;
+
+Operator ** (a, b : FVector) res : FVector;
+
+Begin
+ res.X := a.Y * b.Z - a.Z * b.Y;
+ res.Y := a.Z * b.X - a.X * b.Z;
+ res.Z := a.X * b.Y - a.Y * b.X;
+End;
+
+Constructor FMatrix.Init;
+
+Begin
+End;
+
+Constructor FMatrix.Init(a, b, c : FVector);
+
+Begin
+ Row[0] := a;
+ Row[1] := b;
+ Row[2] := c;
+End;
+
+Function FMatrix.Column0 : FVector;
+
+Var
+ res : FVector;
+
+Begin
+ res.Init(Row[0].X, Row[1].X, Row[2].X);
+ Column0 := res;
+End;
+
+Function FMatrix.Column1 : FVector;
+
+Var
+ res : FVector;
+
+Begin
+ res.Init(Row[0].Y, Row[1].Y, Row[2].Y);
+ Column1 := res;
+End;
+
+Function FMatrix.Column2 : FVector;
+
+Var
+ res : FVector;
+
+Begin
+ res.Init(Row[0].Z, Row[1].Z, Row[2].Z);
+ Column2 := res;
+End;
+
+Procedure FMatrix.MakeXRot(theta : Single);
+
+Var
+ c, s : Single;
+
+Begin
+ c := cos(theta);
+ s := sin(theta);
+ Row[1].Y := c; Row[1].Z := s; Row[1].X := 0;
+ Row[2].Y := -s; Row[2].Z := c; Row[2].X := 0;
+ Row[0].Y := 0; Row[0].Z := 0; Row[0].X := 1;
+End;
+
+Procedure FMatrix.MakeYRot(theta : Single);
+
+Var
+ c, s : Single;
+
+Begin
+ c := cos(theta);
+ s := sin(theta);
+ Row[2].Z := c; Row[2].X := s; Row[2].Y := 0;
+ Row[0].Z := -s; Row[0].X := c; Row[0].Y := 0;
+ Row[1].Z := 0; Row[1].X := 0; Row[1].Y := 1;
+End;
+
+Procedure FMatrix.MakeZRot(theta : Single);
+
+Var
+ c, s : Single;
+
+Begin
+ c := cos(theta);
+ s := sin(theta);
+ Row[0].X := c; Row[0].Y := s; Row[0].Z := 0;
+ Row[1].X := -s; Row[1].Y := c; Row[1].Z := 0;
+ Row[2].X := 0; Row[2].Y := 0; Row[2].Z := 1;
+End;
+
+Procedure FMatrix.MakeID;
+
+Begin
+ Row[0].Init(1, 0, 0);
+ Row[1].Init(0, 1, 0);
+ Row[2].Init(0, 0, 1);
+End;
+
+Function FMatrix.Transpose : FMatrix;
+
+Var
+ res : FMatrix;
+
+Begin
+ res.Init(Column0, Column1, Column2);
+ Transpose := res;
+End;
+
+Procedure FMatrix.TransposeInPlace;
+
+Begin
+ Init(Column0, Column1, Column2);
+End;
+
+Procedure FMatrix.Normalise;
+
+Begin
+ Row[2].Normalise;
+ Row[0] := Row[1]**Row[2];
+ Row[0].Normalise;
+ Row[1] := Row[2]**Row[0];
+ Row[1].Normalise;
+End;
+
+Operator * (Const m : FMatrix; Const a : Single) res : FMatrix;
+
+Begin
+ res.Init(m.Row[0]*a, m.Row[1]*a, m.Row[2]*a);
+End;
+
+Operator * (Const m, a : FMatrix) res : FMatrix;
+
+Var
+ v1, v2, v3 : FVector;
+
+Begin
+ v1.Init(m.Row[0].X*a.Row[0].X+m.Row[0].Y*a.Row[1].X+m.Row[0].Z*a.Row[2].X,
+ m.Row[0].X*a.Row[0].Y+m.Row[0].Y*a.Row[1].Y+m.Row[0].Z*a.Row[2].Y,
+ m.Row[0].X*a.Row[0].Z+m.Row[0].Y*a.Row[1].Z+m.Row[0].Z*a.Row[2].Z);
+ v2.Init(m.Row[1].X*a.Row[0].X+m.Row[1].Y*a.Row[1].X+m.Row[1].Z*a.Row[2].X,
+ m.Row[1].X*a.Row[0].Y+m.Row[1].Y*a.Row[1].Y+m.Row[1].Z*a.Row[2].Y,
+ m.Row[1].X*a.Row[0].Z+m.Row[1].Y*a.Row[1].Z+m.Row[1].Z*a.Row[2].Z);
+ v3.Init(m.Row[2].X*a.Row[0].X+m.Row[2].Y*a.Row[1].X+m.Row[2].Z*a.Row[2].X,
+ m.Row[2].X*a.Row[0].Y+m.Row[2].Y*a.Row[1].Y+m.Row[2].Z*a.Row[2].Y,
+ m.Row[2].X*a.Row[0].Z+m.Row[2].Y*a.Row[1].Z+m.Row[2].Z*a.Row[2].Z);
+ res.Init(v1, v2, v3);
+End;
+
+Operator * (Const m : FMatrix; Const a : FVector) res : FVector;
+
+Begin
+ res.Init(a*m.Row[0], a*m.Row[1], a*m.Row[2]);
+End;
+
+Operator + (Const m, a : FMatrix) res : FMatrix;
+
+Begin
+ res.Init(m.Row[0]+a.Row[0], m.Row[1]+a.Row[1], m.Row[2]+a.Row[2]);
+End;
+
+Operator - (Const m, a : FMatrix) res : FMatrix;
+
+Begin
+ res.Init(m.Row[0]+a.Row[0], m.Row[1]+a.Row[1], m.Row[2]+a.Row[2]);
+End;
+
+Constructor TRay.Init(Const p, d : FVector);
+
+Begin
+ mPosn := p;
+ mDir := d;
+ mDir.Normalise;
+End;
+
+Constructor VLight.Create(Const col : FVector);
+
+Begin
+ mCol := col * 0.9;
+ mAng := 2.8;
+ mPosn.Init(0, 0, 20);
+ mTarget.Init(0, 0, 0.1);
+ mAxis.MakeID;
+ Update;
+End;
+
+Procedure VLight.Move(Const q : FVector);
+
+Begin
+ mPosn := q;
+ Update;
+End;
+
+Procedure VLight.MoveT(Const q : FVector);
+
+Begin
+ mTarget := q;
+ Update;
+End;
+
+Procedure VLight.Update;
+
+Begin
+ mAxis.Row[2] := (mTarget - mPosn);
+ mAxis.Normalise;
+End;
+
+Function VLight.Light(Const ray : TRay) : FVector;
+
+Var
+ f, A, B, C, D, t1, t2, t3, fr, l1, l2, t, h : Single;
+ frc, x, y, q : Integer;
+ pp : FVector;
+ res : FVector;
+
+Begin
+ f := 0;
+
+ p2 := ray.mPosn;
+ p := mAxis * (ray.mPosn - mPosn);
+ _d := mAxis * ray.mDir;
+ A := (_d.X*_d.X+_d.Y*_d.Y);
+ B := 2*(_d.X*p.X+_d.Y*p.Y)-mAng*(_d.Z);
+ C := (p.X*p.X+p.Y*p.Y)-mAng*(p.Z);
+ D := B*B-4*A*C;
+ If D <= 0 Then
+ Begin
+ res.Init(0, 0, 0);
+ Light := res;
+ Exit;
+ End;
+ D := Sqrt(D);
+ A *= 2;
+ t1 := (-B-D)/A;
+ t2 := (-B+D)/A;
+ frc := 255;
+ t3 := -ray.mPosn.Z/ray.mDir.Z;
+ If t2<=0 Then
+ Begin
+ res.Init(0, 0, 0);
+ Light := res;
+ Exit;
+ End;
+ If t1<0 Then
+ t1 := 0;
+ If t3>0 Then
+ Begin
+ { clip to bitmap plane }
+ pp := ray.mPosn + ray.mDir*t3;
+ x := 160+Trunc(SC*pp.X);
+{$IFNDEF INV}
+ If (x>=0) And (x<=319) Then
+ Begin
+ y := 100 + Trunc(SC*pp.Y);
+ If (y>=0) And (y<=199) Then
+ Begin
+ {res.Init(0, 0, 1);
+ Light := res;
+ Exit;}
+ frc := MaskMap[y*320+x];
+ If frc<1 Then
+ Begin
+ If t1>t3 Then
+ t1 := t3;
+ If t2>t3 Then
+ t2 := t3;
+ End;
+ End
+ Else
+ t3 := t2
+ End
+ Else
+ t3 := t2;
+{$ELSE}
+ If (x >= 0) And (x <= 319) Then
+ Begin
+ y := 100 + Trunc(SC*pp.Y);
+ If (y >= 0) And (y <= 199) And (MaskMap[y*320 + x] < 128) Then
+ t3 := t2;
+ End;
+ If t1 > t3 Then
+ t1 := t3;
+ If t2 > t3 Then
+ t2 := t3;
+{$ENDIF}
+ End;
+ If t1>=t2 Then
+ Begin
+ res.Init(0, 0, 0);
+ Light := res;
+ Exit;
+ End;
+ fr := frc/255;
+ l1 := CalcLight(t1);
+ If t1>t3 Then
+ l1 *= fr;
+ q := NSEG;
+ t := t1;
+ h := (t2-t1)/NSEG;
+ If h<MINSEGSIZE Then
+ h := MINSEGSIZE;
+ While (t<t3) And (q>0) And (t<t2) Do
+ Begin
+ t += h;
+ If (t>t2) Then
+ Begin
+ h -= t2-t;
+ t := t2;
+ q := 0;
+ End
+ Else
+ Dec(q);
+ h := (t-t1);
+ p += _d*h;
+ p2 += ray.mDir*h;
+ l2 := CalcLight(t);
+ f += (l1+l2)*h;
+ l1 := l2;
+ t1 := t;
+ End;
+ While (q>0) And (t<t2) Do
+ Begin
+ t += h;
+ If t>t2 Then
+ Begin
+ h -= t2-t;
+ t := t2;
+ q := 0;
+ End
+ Else
+ Dec(q);
+ p += _d*h;
+ p2 += ray.mDir*h;
+ l2 := CalcLight(t);
+ If t>t3 Then
+ l2 *= fr;
+ f += (l1+l2)*h;
+ l1 := l2;
+ t1 := t;
+ End;
+ Light := mCol*f;
+End;
+
+Function VLight.CalcLight(t : Single) : Single;
+
+Var
+ f : Single;
+ x, y, c : Integer;
+
+Begin
+ { trace line to bitmap from mPosn to p2 }
+ If Not ((mPosn.Z > 0) Xor (p2.Z > 0)) Then
+ Begin
+ { fresnel fall off... }
+ CalcLight := p.Z / p.MagnitudeSq;
+ Exit;
+ End;
+ f := -(mPosn.Z)/(p2.Z - mPosn.Z);
+ x := 160 + Trunc(SC*((p2.X-mPosn.X)*f+mPosn.X));
+{$IFNDEF INV}
+ If (x < 0) Or (x > 319) Then
+ Begin
+ CalcLight := p.Z / p.MagnitudeSq;
+ Exit;
+ End;
+ y := 100 + Trunc(SC*((p2.Y-mPosn.Y)*f+mPosn.Y));
+ If (y < 0) Or (y > 199) Then
+ Begin
+ CalcLight := p.Z / p.MagnitudeSq;
+ Exit;
+ End;
+ c := MaskMap[y * 320 + x];
+{$ELSE}
+ If (x < 0) Or (x > 319) Then
+ Begin
+ CalcLight := 0;
+ Exit;
+ End;
+ y := 100 + Trunc(SC*((p2.Y-mPosn.Y)*f+mPosn.Y));
+ If (y < 0) Or (y > 199) Then
+ Begin
+ CalcLight := 0;
+ Exit;
+ End;
+ c := 255 - MaskMap[y * 320 + x];
+{$ENDIF}
+ If c = 0 Then
+ Begin
+ CalcLight := 0;
+ Exit;
+ End;
+ CalcLight := (c*(1/255))*p.Z / p.MagnitudeSq;
+End;
+
+Function CLIPC(f : Single) : Integer; {Inline;}
+
+Var
+ a : Integer;
+
+Begin
+ a := Trunc(f * 255);
+ If a < 0 Then
+ a := 0
+ Else
+ If a > 255 Then
+ a := 255;
+ CLIPC := a;
+End;
+
+Procedure initfrand;
+
+Var
+ s, c1 : Integer;
+
+Begin
+ FillChar(frandtab, SizeOf(frandtab), 0);
+ s := 1;
+ For c1 := 1 To 65535 Do
+ Begin
+ frandtab[c1] := s And $FFFF;
+ s := (((s Shr 4) Xor (s Shr 13) Xor (s Shr 15)) And 1) + (s Shl 1);
+ End;
+End;
+
+Function frand : Integer; {Inline;}
+
+Begin
+ frand := frandtab[frandtab_seed];
+ frandtab_seed := (frandtab_seed + 1) And $FFFF;
+End;
+
+Procedure VLightPart(console : TPTCConsole; surface : TPTCSurface);
+
+Var
+ vl, vl2 : VLight;
+ camposn : FVector;
+ camaxis : FMatrix;
+ c1, c2, c3, ti, xx, yy, zz, i, a, x, y : Integer;
+ idx : Array[0..(200 Div 16) - 1, 0..(320 Div 16) - 1] Of Uint8;
+ order : Array[0..10*19 - 1, 0..1] Of Integer;
+ vlightt, t, cz, camf : Single;
+ col : FVector;
+ ray : TRay;
+ oc, c, c2_ : Uint32;
+ time, delta : Single;
+ pitch : Integer;
+ screenbuf, pd : PUint8;
+ tmp : FVector;
+ F : File;
+
+Begin
+ oc := 0;
+ initfrand;
+ tmp.Init(0.1, 0.4, 1);
+ vl := VLight.Create(tmp);
+ tmp.Init(1, 0.5, 0.2);
+ vl2 := VLight.Create(tmp);
+ tmp.Init(0, 0, 20);
+ vl.Move(tmp);
+ tmp.Init(0, 6, 30);
+ vl2.Move(tmp);
+
+ camposn.Init(7, 0.5, -10);
+ camaxis.Init;
+ camaxis.MakeID;
+ tmp.Init(0, 0, 0);
+ camaxis.Row[2] := tmp - camposn;
+ camaxis.Normalise;
+ camf := 100;
+
+ MaskMap := GetMem(320 * 200);
+ FillChar(MaskMap^, 320 * 200, 0);
+
+ { load mojo.raw }
+ ASSign(F, 'mojo.raw');
+ Reset(F, 1);
+ BlockRead(F, MaskMap^, 320*200);
+ Close(F);
+
+ { build the order of the squares }
+ For c1 := 0 To 10*19 - 1 Do
+ Begin
+ order[c1, 0] := c1 Mod 19;
+ order[c1, 1] := (c1 Div 19) + 1;
+ End;
+
+ { swap them around }
+ For c1 := 0 To 9999 Do
+ Begin
+ c2 := Random(190);
+ c3 := Random(190);
+ ti := order[c2, 0]; order[c2, 0] := order[c3, 0]; order[c3, 0] := ti;
+ ti := order[c2, 1]; order[c2, 1] := order[c3, 1]; order[c3, 1] := ti;
+ End;
+
+ { time settings }
+ time := 0;
+ delta := 0.01; { this controls the speed of the effect }
+
+ { main loop }
+ While Not console.KeyPressed Do
+ Begin
+ { get surface data }
+ pitch := surface.pitch;
+
+ { light time (makes the effect loop) }
+ vlightt := 320 * Abs(Sin(time/5));
+
+ t := 13 - 0.1822 * vlightt;
+ cz := 1 - 0.01 * vlightt;
+ {tmp.Init(Sin(t)*5, Cos(t*-0.675+4543)*5, 15);
+ vl.Move(tmp);
+ tmp.Init(0, 0, -15);
+ vl.Move(tmp);}
+ tmp.Init(t, 0, 22);
+ vl.Move(tmp);
+ tmp.Init(-t, -7, 28);
+ vl2.Move(tmp);
+
+ camposn.Init(cz*4+9, cz, -t/7-13);
+ tmp.Init(0, 0, 0);
+ camaxis.Row[2] := tmp - camposn;
+ camaxis.Normalise;
+
+ FillChar(idx, SizeOf(idx), 25);
+
+ { swap them around }
+ For c1 := 0 To 99 Do
+ Begin
+ c2 := Random(190);
+ c3 := Random(190);
+ ti := order[c2, 0]; order[c2, 0] := order[c3, 0]; order[c3, 0] := ti;
+ ti := order[c2, 1]; order[c2, 1] := order[c3, 1]; order[c3, 1] := ti;
+ End;
+ For zz := 0 To 189 Do
+ Begin
+ xx := order[zz, 0];
+ yy := order[zz, 1];
+ i := 0;
+
+ { lock surface }
+ screenbuf := surface.lock;
+ Try
+ c2 := idx[yy, xx] Shr 1;
+ For c1 := 0 To c2 - 1 Do
+ Begin
+ a := frand And 255;
+ x := xx * 16 + (a And 15) + 6 + 4;
+ y := yy * 16 + (a Shr 4) + 6;
+
+ col.Init(0, 0, 0);
+ ray.Init(camposn, camaxis.Row[2]*camf+camaxis.Row[0]*(x-160)+camaxis.Row[1]*(y-100));
+ col += vl.Light(ray);
+ col += vl2.Light(ray);
+
+ c := (CLIPC(col.X) Shl 16) + (CLIPC(col.Y) Shl 8) + (CLIPC(col.Z));
+ pd := screenbuf + x*4 + y*pitch;
+ Inc(i, Abs(Integer(c And 255)-Integer(pd[321] And 255)) + Abs(Integer(c Shr 16)-Integer(pd[321] Shr 16)));
+ If c1 <> 0 Then
+ Inc(i, Abs(Integer(c And 255)-Integer(oc And 255)) + Abs(Integer(c Shr 16)-Integer(oc Shr 16)));
+ oc := c;
+
+ c2_ := (c Shr 1) And $7F7F7F;
+ PUint32(pd)[1] := ((PUint32(pd)[1]) Shr 1) And $7F7F7F+ c2_;
+ PUint32(pd)[2] := ((PUint32(pd)[2]) Shr 1) And $7F7F7F+ c2_;
+ Inc(pd, pitch);
+ PUint32(pd)[0] := ((PUint32(pd)[0]) Shr 1) And $7F7F7F+ c2_;
+ PUint32(pd)[1] := c;
+ PUint32(pd)[2] := c;
+ PUint32(pd)[3] := ((PUint32(pd)[3]) Shr 1) And $7F7F7F+ c2_;
+ Inc(pd, pitch);
+ PUint32(pd)[0] := ((PUint32(pd)[0]) Shr 1) And $7F7F7F+ c2_;
+ PUint32(pd)[1] := c;
+ PUint32(pd)[2] := c;
+ PUint32(pd)[3] := ((PUint32(pd)[3]) Shr 1) And $7F7F7F+ c2_;
+ Inc(pd, pitch);
+ PUint32(pd)[1] := ((PUint32(pd)[1]) Shr 1) And $7F7F7F+ c2_;
+ PUint32(pd)[2] := ((PUint32(pd)[2]) Shr 1) And $7F7F7F+ c2_;
+ End;
+ i *= 5;
+ i := i Div (3*idx[yy, xx]);
+ If i < 2 Then
+ i := 2;
+ If i > {256}255 Then
+ i := {256}255;
+ idx[yy, xx] := i;
+ Finally
+ { unlock surface }
+ surface.unlock;
+ End;
+
+ If (zz Mod 95) = 0 Then
+ Begin
+ { copy surface to console }
+ surface.copy(console);
+
+ { update console }
+ console.update;
+ End;
+ End;
+ { update time }
+ time += delta;
+ End;
+ FreeMem(MaskMap);
+ vl.Free;
+ vl2.Free;
+End;
+
+Var
+ format : TPTCFormat;
+ console : TPTCConsole;
+ surface : TPTCSurface;
+
+Begin
+ format := Nil;
+ surface := Nil;
+ console := Nil;
+ Try
+ Try
+ { create format }
+ format := TPTCFormat.Create(32, $00FF0000, $0000FF00, $000000FF);
+
+ { create console }
+ console := TPTCConsole.Create;
+
+ { open console }
+ console.open('mojo by statix', 320, 200, format);
+
+ { create main drawing surface }
+ surface := TPTCSurface.Create(320, 200, format);
+
+ { do the light effect }
+ VLightPart(console, surface);
+
+ Finally
+ { close console }
+ console.close;
+ console.Free;
+ surface.Free;
+ format.Free;
+ End;
+
+ { print message to stdout }
+ Writeln('mojo by alex "statix" evans');
+ Writeln('to be used as an example of bad coding and good ptc');
+ Writeln('no responsibility taken for this!');
+ Writeln('enjoy ptc! it''s great');
+ Writeln;
+ Writeln('-statix 13/1/98');
+ Except
+ On error : TPTCError Do
+ { report error }
+ error.report;
+ End;
+End.
diff --git a/packages/ptc/examples/mojo.raw b/packages/ptc/examples/mojo.raw
new file mode 100644
index 0000000000..3ef71a7858
--- /dev/null
+++ b/packages/ptc/examples/mojo.raw
Binary files differ
diff --git a/packages/ptc/examples/palette.pp b/packages/ptc/examples/palette.pp
new file mode 100644
index 0000000000..c9e53561b7
--- /dev/null
+++ b/packages/ptc/examples/palette.pp
@@ -0,0 +1,102 @@
+{
+Ported to FPC by Nikolay Nikolov (nickysn@users.sourceforge.net)
+}
+
+{
+ Palette example for OpenPTC 1.0 C++ Implementation
+ Copyright (c) Glenn Fiedler (ptc@gaffer.org)
+ This source code is in the public domain
+}
+
+Program PaletteExample;
+
+{$MODE objfpc}
+
+Uses
+ ptc;
+
+Var
+ console : TPTCConsole;
+ surface : TPTCSurface;
+ format : TPTCFormat;
+ palette : TPTCPalette;
+ data : Array[0..255] Of int32;
+ pixels : Pchar8;
+ width, height : Integer;
+ i : Integer;
+ x, y, index : Integer;
+
+Begin
+ Try
+ { create console }
+ console := TPTCConsole.Create;
+
+ { create format }
+ format := TPTCFormat.Create(8);
+
+ { open console }
+ console.open('Palette example', format);
+
+ { create surface }
+ surface := TPTCSurface.Create(console.width, console.height, format);
+ format.Free;
+
+ { create palette }
+ palette := TPTCPalette.Create;
+
+ { generate palette }
+ For i := 0 To 255 Do
+ data[i] := i;
+
+ { load palette data }
+ palette.load(data);
+
+ { set console palette }
+ console.palette(palette);
+
+ { set surface palette }
+ surface.palette(palette);
+ palette.Free;
+
+ { loop until a key is pressed }
+ While Not console.KeyPressed Do
+ Begin
+ { lock surface }
+ pixels := surface.lock;
+
+ { get surface dimensions }
+ width := surface.width;
+ height := surface.height;
+
+ { draw random pixels }
+ For i := 1 To 100 Do
+ Begin
+ { get random position }
+ x := Random(width);
+ y := Random(height);
+
+ { get random color index }
+ index := Random(256);
+
+ { draw color [index] at position [x,y] }
+ pixels[x + y * width] := index;
+ End;
+
+ { unlock surface }
+ surface.unlock;
+
+ { copy to console }
+ surface.copy(console);
+
+ { update console }
+ console.update;
+ End;
+ console.close;
+ console.Free;
+ surface.Free;
+ Except
+ On error : TPTCError Do
+ { report error }
+ error.report;
+ End;
+End.
diff --git a/packages/ptc/examples/pixel.pp b/packages/ptc/examples/pixel.pp
new file mode 100644
index 0000000000..701612c5b2
--- /dev/null
+++ b/packages/ptc/examples/pixel.pp
@@ -0,0 +1,84 @@
+{
+Ported to FPC by Nikolay Nikolov (nickysn@users.sourceforge.net)
+}
+
+{
+ Pixel example for OpenPTC 1.0 C++ API
+ Copyright (c) Glenn Fiedler (ptc@gaffer.org)
+ This source code is licensed under the GNU GPL
+}
+
+Program PixelExample;
+
+{$MODE objfpc}
+
+Uses
+ ptc;
+
+Procedure putpixel(surface : TPTCSurface; x, y : Integer; r, g, b : char8);
+
+Var
+ pixels : Pint32;
+ color : int32;
+
+Begin
+ { lock surface }
+ pixels := surface.lock;
+ Try
+ { pack the color integer from r,g,b components }
+ color := (r Shl 16) Or (g Shl 8) Or b;
+
+ { plot the pixel on the surface }
+ pixels[x + y * surface.width] := color;
+ Finally
+ { unlock surface }
+ surface.unlock;
+ End;
+End;
+
+Var
+ console : TPTCConsole;
+ surface : TPTCSurface;
+ format : TPTCFormat;
+
+Begin
+ format := Nil;
+ surface := Nil;
+ console := Nil;
+ Try
+ Try
+ { create console }
+ console := TPTCConsole.Create;
+
+ { create format }
+ format := TPTCFormat.Create(32, $00FF0000, $0000FF00, $000000FF);
+
+ { open the console }
+ console.open('Pixel example', format);
+
+ { create surface matching console dimensions }
+ surface := TPTCSurface.Create(console.width, console.height, format);
+
+ { plot a white pixel in the middle of the surface }
+ putpixel(surface, surface.width Div 2, surface.height Div 2, 255, 255, 255);
+
+ { copy to console }
+ surface.copy(console);
+
+ { update console }
+ console.update;
+
+ { read key }
+ console.ReadKey;
+ Finally
+ console.close;
+ console.Free;
+ surface.Free;
+ format.Free;
+ End;
+ Except
+ On error : TPTCError Do
+ { report error }
+ error.report;
+ End;
+End.
diff --git a/packages/ptc/examples/random.pp b/packages/ptc/examples/random.pp
new file mode 100644
index 0000000000..e898f0192b
--- /dev/null
+++ b/packages/ptc/examples/random.pp
@@ -0,0 +1,92 @@
+{
+Ported to FPC by Nikolay Nikolov (nickysn@users.sourceforge.net)
+}
+
+{
+ Random example for OpenPTC 1.0 C++ Implementation
+ Copyright (c) Glenn Fiedler (ptc@gaffer.org)
+ This source code is in the public domain
+}
+
+Program RandomExample;
+
+{$MODE objfpc}
+
+Uses
+ ptc;
+
+Var
+ console : TPTCConsole;
+ surface : TPTCSurface;
+ format : TPTCFormat;
+ pixels : Pint32;
+ width, height : Integer;
+ i : Integer;
+ x, y, r, g, b : Integer;
+
+Begin
+ format := Nil;
+ surface := Nil;
+ console := Nil;
+ Try
+ Try
+ { create console }
+ console := TPTCConsole.Create;
+
+ { create format }
+ format := TPTCFormat.Create(32, $00FF0000, $0000FF00, $000000FF);
+
+ { open the console }
+ console.open('Random example', format);
+
+ { create surface matching console dimensions }
+ surface := TPTCSurface.Create(console.width, console.height, format);
+
+ { loop until a key is pressed }
+ While Not console.KeyPressed Do
+ Begin
+ { lock surface }
+ pixels := surface.lock;
+ Try
+ { get surface dimensions }
+ width := surface.width;
+ height := surface.height;
+
+ { draw random pixels }
+ For i := 1 To 100 Do
+ Begin
+ { get random position }
+ x := Random(width);
+ y := Random(height);
+
+ { get random color }
+ r := Random(256);
+ g := Random(256);
+ b := Random(256);
+
+ { draw color [r,g,b] at position [x,y] }
+ pixels[x + y * width] := (r Shl 16) + (g Shl 8) + b;
+ End;
+ Finally
+ { unlock surface }
+ surface.unlock;
+ End;
+
+ { copy to console }
+ surface.copy(console);
+
+ { update console }
+ console.update;
+ End;
+ Finally
+ console.close;
+ console.Free;
+ surface.Free;
+ format.Free;
+ End;
+ Except
+ On error : TPTCError Do
+ { report error }
+ error.report;
+ End;
+End.
diff --git a/packages/ptc/examples/save.pp b/packages/ptc/examples/save.pp
new file mode 100644
index 0000000000..a579295e5d
--- /dev/null
+++ b/packages/ptc/examples/save.pp
@@ -0,0 +1,290 @@
+{
+Ported to FPC by Nikolay Nikolov (nickysn@users.sourceforge.net)
+}
+
+{
+ Save example for OpenPTC 1.0 C++ Implementation
+ Copyright (c) Glenn Fiedler (ptc@gaffer.org)
+ This source code is in the public domain
+}
+
+Program SaveExample;
+
+{$MODE objfpc}
+
+Uses
+ ptc, Math;
+
+Procedure save(surface : TPTCSurface; filename : String);
+
+Const
+ { generate the header for a true color targa image }
+ header : Array[0..17] Of char8 =
+ (0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+
+Var
+ F : File;
+ width, height : Integer;
+ size : Integer;
+ y : Integer;
+ pixels : Pchar8;
+ format : TPTCFormat;
+ palette : TPTCPalette;
+
+Begin
+ { open image file for writing }
+ ASSign(F, filename);
+ Rewrite(F, 1);
+
+ { get surface dimensions }
+ width := surface.width;
+ height := surface.height;
+
+ { set targa image width }
+ header[12] := width And $FF;
+ header[13] := width Shr 8;
+
+ { set targa image height }
+ header[14] := height And $FF;
+ header[15] := height Shr 8;
+
+ { set bits per pixel }
+ header[16] := 24;
+
+ { write tga header }
+ BlockWrite(F, header, 18);
+
+ { calculate size of image pixels }
+ size := width * height * 3;
+
+ { allocate image pixels }
+ pixels := GetMem(size);
+
+ format := TPTCFormat.Create(24, $00FF0000, $0000FF00, $000000FF);
+ palette := TPTCPalette.Create;
+
+ { save surface to image pixels }
+ surface.save(pixels, width, height, width * 3, format, palette);
+
+ palette.Free;
+ format.Free;
+
+ { write image pixels one line at a time }
+ For y := height - 1 DownTo 0 Do
+ BlockWrite(F, pixels[width * y * 3], width * 3);
+
+ { free image pixels }
+ FreeMem(pixels);
+
+ Close(F);
+End;
+
+Function calculate(real, imaginary : Single; maximum : Integer) : Integer;
+
+Var
+ c_r, c_i : Single;
+ z_r, z_i : Single;
+ z_r_squared, z_i_squared : Single;
+ z_squared_magnitude : Single;
+ count : Integer;
+
+Begin
+ { complex number 'c' }
+ c_r := real;
+ c_i := imaginary;
+
+ { complex 'z' }
+ z_r := 0;
+ z_i := 0;
+
+ { complex 'z' squares }
+ z_r_squared := 0;
+ z_i_squared := 0;
+
+ { mandelbrot function iteration loop }
+ For count := 0 To maximum - 1 Do
+ Begin
+ { square 'z' and add 'c' }
+ z_i := 2 * z_r * z_i + c_i;
+ z_r := z_r_squared - z_i_squared + c_r;
+
+ { update 'z' squares }
+ z_r_squared := z_r * z_r;
+ z_i_squared := z_i * z_i;
+
+ { calculate squared magnitude of complex 'z' }
+ z_squared_magnitude := z_r_squared + z_i_squared;
+
+ { stop iterating if the magnitude of 'z' is greater than two }
+ If z_squared_magnitude > 4 Then
+ Begin
+ calculate := Count;
+ Exit;
+ End;
+ End;
+
+ { maximum }
+ calculate := 0;
+End;
+
+Procedure mandelbrot(console : TPTCConsole; surface : TPTCSurface;
+ x1, y1, x2, y2 : Single);
+
+Const
+ { constant values }
+ entries = 1024;
+ maximum = 1024;
+
+Var
+ { fractal color table }
+ table : Array[0..entries - 1] Of int32;
+ i : Integer;
+ f_index : Single;
+ time : Single;
+ intensity : Single;
+ pixels, pixel : Pint32;
+ width, height : Integer;
+ dx, dy : Single;
+ real, imaginary : Single;
+ x, y : Integer;
+ count : Integer;
+ index : Integer;
+ color : int32;
+ area : TPTCArea;
+
+Begin
+ { generate fractal color table }
+ For i := 0 To entries - 1 Do
+ Begin
+ { calculate normalized index }
+ f_index := i / entries;
+
+ { calculate sine curve time value }
+ time := f_index * pi - pi / 2;
+
+ { lookup sine curve intensity at time and scale to [0,1] }
+ intensity := (sin(time) + 1) / 2;
+
+ { raise the intensity to a power }
+ intensity := power(intensity, 0.1);
+
+ { store intensity as a shade of blue }
+ table[i] := Trunc(255 * intensity);
+ End;
+
+ { lock surface pixels }
+ pixels := surface.lock;
+ Try
+ { get surface dimensions }
+ width := surface.width;
+ height := surface.height;
+
+ { current pixel pointer }
+ pixel := pixels;
+
+ { calculate real x,y deltas }
+ dx := (x2 - x1) / width;
+ dy := (y2 - y1) / height;
+
+ { imaginary axis }
+ imaginary := y1;
+
+ { iterate down surface y }
+ For y := 0 To height - 1 Do
+ Begin
+ { real axis }
+ real := x1;
+
+ { iterate across surface x }
+ For x := 0 To width - 1 Do
+ Begin
+ { calculate the mandelbrot interation count }
+ count := calculate(real, imaginary, maximum);
+
+ { calculate color table index }
+ index := count Mod entries;
+
+ { lookup color from iteration }
+ color := table[index];
+
+ { store color }
+ pixel^ := color;
+
+ { next pixel }
+ Inc(pixel);
+
+ { update real }
+ real := real + dx;
+ End;
+
+ { update imaginary }
+ imaginary := imaginary + dy;
+
+ { setup line area }
+ area := TPTCArea.Create(0, y, width, y + 1);
+ Try
+ { copy surface area to console }
+ surface.copy(console, area, area);
+ Finally
+ area.Free;
+ End;
+
+ { update console area }
+ console.update;
+ End;
+ Finally
+ { unlock surface }
+ surface.unlock;
+ End;
+End;
+
+Var
+ console : TPTCConsole;
+ surface : TPTCSurface;
+ format : TPTCFormat;
+ x1, y1, x2, y2 : Single;
+
+Begin
+ format := Nil;
+ surface := Nil;
+ console := Nil;
+ Try
+ Try
+ { create console }
+ console := TPTCConsole.Create;
+
+ { create format }
+ format := TPTCFormat.Create(32, $00FF0000, $0000FF00, $000000FF);
+
+ { open the console with a single page }
+ console.open('Save example', format, 1);
+
+ { create surface matching console dimensions }
+ surface := TPTCSurface.Create(console.width, console.height, format);
+
+ { setup viewing area }
+ x1 := -2.00;
+ y1 := -1.25;
+ x2 := +1.00;
+ y2 := +1.25;
+
+ { render the mandelbrot fractal }
+ mandelbrot(console, surface, x1, y1, x2, y2);
+
+ { save mandelbrot image }
+ save(surface, 'save.tga');
+
+ { read key }
+ console.ReadKey;
+ Finally
+ console.close;
+ console.Free;
+ surface.Free;
+ format.Free;
+ End;
+ Except
+ On error : TPTCError Do
+ { report error }
+ error.report;
+ End;
+End.
diff --git a/packages/ptc/examples/stretch.pp b/packages/ptc/examples/stretch.pp
new file mode 100644
index 0000000000..f7cf768b0d
--- /dev/null
+++ b/packages/ptc/examples/stretch.pp
@@ -0,0 +1,164 @@
+{
+Ported to FPC by Nikolay Nikolov (nickysn@users.sourceforge.net)
+}
+
+{
+ Stretch example for OpenPTC 1.0 C++ Implementation
+ Copyright (c) Glenn Fiedler (ptc@gaffer.org)
+ This source code is in the public domain
+}
+
+Program StretchExample;
+
+{$MODE objfpc}
+
+Uses
+ ptc;
+
+Procedure load(surface : TPTCSurface; filename : String);
+
+Var
+ F : File;
+ width, height : Integer;
+ pixels : PByte;
+ y : Integer;
+ tmp : TPTCFormat;
+ tmp2 : TPTCPalette;
+
+Begin
+ { open image file }
+ ASSign(F, filename);
+ Reset(F, 1);
+
+ { skip header }
+ Seek(F, 18);
+
+ { get surface dimensions }
+ width := surface.width;
+ height := surface.height;
+
+ { allocate image pixels }
+ pixels := GetMem(width * height * 3);
+ Try
+ { read image pixels one line at a time }
+ For y := height - 1 DownTo 0 Do
+ BlockRead(F, pixels[width * y * 3], width * 3);
+
+ { load pixels to surface }
+ tmp := TPTCFormat.Create(24, $00FF0000, $0000FF00, $000000FF);
+ Try
+ tmp2 := TPTCPalette.Create;
+ Try
+ surface.load(pixels, width, height, width * 3, tmp, tmp2);
+ Finally
+ tmp2.Free;
+ End;
+ Finally
+ tmp.Free;
+ End;
+ Finally
+ { free image pixels }
+ FreeMem(pixels);
+ End;
+End;
+
+Var
+ console : TPTCConsole;
+ surface : TPTCSurface;
+ image : TPTCSurface;
+ format : TPTCFormat;
+ timer : TPTCTimer;
+ area : TPTCArea;
+ color : TPTCColor;
+ time : Double;
+ zoom : Single;
+ x, y, x1, y1, x2, y2, dx, dy : Integer;
+
+Begin
+ format := Nil;
+ color := Nil;
+ timer := Nil;
+ image := Nil;
+ surface := Nil;
+ console := Nil;
+ Try
+ Try
+ { create console }
+ console := TPTCConsole.Create;
+
+ { create format }
+ format := TPTCFormat.Create(32, $00FF0000, $0000FF00, $000000FF);
+
+ { open the console }
+ console.open('Stretch example', format);
+
+ { create surface matching console dimensions }
+ surface := TPTCSurface.Create(console.width, console.height, format);
+
+ { create image surface }
+ image := TPTCSurface.Create(320, 140, format);
+
+ { load image to surface }
+ load(image, 'stretch.tga');
+
+ { setup stretching parameters }
+ x := surface.width Div 2;
+ y := surface.height Div 2;
+ dx := surface.width Div 2;
+ dy := surface.height Div 3;
+
+ { create timer }
+ timer := TPTCTimer.Create;
+
+ { start timer }
+ timer.start;
+ color := TPTCColor.Create(1, 1, 1);
+
+ { loop until a key is pressed }
+ While Not console.KeyPressed Do
+ Begin
+ { get current time from timer }
+ time := timer.time;
+
+ { clear surface to white background }
+ surface.clear(color);
+
+ { calculate zoom factor at current time }
+ zoom := 2.5 * (1 - cos(time));
+
+ { calculate zoomed image coordinates }
+ x1 := Trunc(x - zoom * dx);
+ y1 := Trunc(y - zoom * dy);
+ x2 := Trunc(x + zoom * dx);
+ y2 := Trunc(y + zoom * dy);
+
+ { setup image copy area }
+ area := TPTCArea.Create(x1, y1, x2, y2);
+ Try
+ { copy and stretch image to surface }
+ image.copy(surface, image.area, area);
+
+ { copy surface to console }
+ surface.copy(console);
+
+ { update console }
+ console.update;
+ Finally
+ area.Free;
+ End;
+ End;
+ Finally
+ console.close;
+ console.Free;
+ surface.Free;
+ format.Free;
+ image.Free;
+ color.Free;
+ timer.Free;
+ End;
+ Except
+ On error : TPTCError Do
+ { report error }
+ error.report;
+ End;
+End.
diff --git a/packages/ptc/examples/stretch.tga b/packages/ptc/examples/stretch.tga
new file mode 100644
index 0000000000..f0441d2bd8
--- /dev/null
+++ b/packages/ptc/examples/stretch.tga
Binary files differ
diff --git a/packages/ptc/examples/texwarp.pp b/packages/ptc/examples/texwarp.pp
new file mode 100644
index 0000000000..81cbb0806c
--- /dev/null
+++ b/packages/ptc/examples/texwarp.pp
@@ -0,0 +1,396 @@
+{
+Ported to FPC by Nikolay Nikolov (nickysn@users.sourceforge.net)
+}
+
+{
+ Texture warp demo for OpenPTC 1.0 C++ API
+ Copyright (c) 1998 Jonathan Matthew
+ This source code is licensed under the GNU GPL
+}
+
+Program TexWarp;
+
+{$MODE objfpc}
+
+Uses
+ ptc;
+
+Const
+{ colour balance values. change these if you don't like the colouring }
+{ of the texture. }
+ red_balance : Uint32 = 2;
+ green_balance : Uint32 = 3;
+ blue_balance : Uint32 = 1;
+
+Procedure blur(s : TPTCSurface);
+
+Var
+ d : PUint8;
+ pitch : Integer;
+ spack, r : Integer;
+
+Begin
+ { lock surface }
+ d := s.lock;
+
+ Try
+ pitch := s.pitch;
+ spack := (s.height - 1) * pitch;
+
+ { first pixel }
+ For r := 0 To 3 Do
+ d[r] := (d[pitch + r] + d[r + 4] + d[spack + r] + d[pitch - 4 + r]) Div 4;
+
+ { rest of first line }
+ For r := 4 To pitch - 1 Do
+ d[r] := (d[r + pitch] + d[r + 4] + d[r - 4] + d[spack + r]) Div 4;
+
+ { rest of surface except last line }
+ For r := pitch To ((s.height - 1) * pitch) - 1 Do
+ d[r] := (d[r - pitch] + d[r + pitch] + d[r + 4] + d[r - 4]) Div 4;
+
+ { last line except last pixel }
+ For r := (s.height - 1) * pitch To (s.height * s.pitch) - 5 Do
+ d[r] := (d[r - pitch] + d[r + 4] + d[r - 4] + d[r - spack]) Div 4;
+
+ { last pixel }
+ For r := (s.height * s.pitch) - 4 To s.height * s.pitch Do
+ d[r] := (d[r - pitch] + d[r - 4] + d[r - spack] + d[r + 4 - pitch]) Div 4;
+
+ Finally
+ s.unlock;
+ End;
+End;
+
+Procedure generate(surface : TPTCSurface);
+
+Var
+ dest : PUint32;
+ i : Integer;
+ x, y : Integer;
+ d : PUint32;
+ cv : Uint32;
+ r, g, b : Uint8;
+
+Begin
+ { draw random dots all over the surface }
+ dest := surface.lock;
+ Try
+ For i := 0 To surface.width * surface.height - 1 Do
+ Begin
+ x := Random(surface.width);
+ y := Random(surface.height);
+ d := dest + (y * surface.width) + x;
+ cv := (Random(100) Shl 16) Or (Random(100) Shl 8) Or Random(100);
+ d^ := cv;
+ End;
+ Finally
+ surface.unlock;
+ End;
+
+ { blur the surface }
+ For i := 1 To 5 Do
+ blur(surface);
+
+ { multiply the color values }
+ dest := surface.lock;
+ Try
+ For i := 0 To surface.width * surface.height - 1 Do
+ Begin
+ cv := dest^;
+ r := (cv Shr 16) And 255;
+ g := (cv Shr 8) And 255;
+ b := cv And 255;
+ r *= red_balance;
+ g *= green_balance;
+ b *= blue_balance;
+ If r > 255 Then
+ r := 255;
+ If g > 255 Then
+ g := 255;
+ If b > 255 Then
+ b := 255;
+ dest^ := (r Shl 16) Or (g Shl 8) Or b;
+ Inc(dest);
+ End;
+ Finally
+ surface.unlock;
+ End;
+End;
+
+Procedure grid_map(grid : PUint32; xbase, ybase, xmove, ymove, amp : Single);
+
+Var
+ x, y : Integer;
+ a, b, id : Single;
+
+Begin
+ a := 0;
+ For y := 0 To 25 Do
+ Begin
+ b := 0;
+ For x := 0 To 40 Do
+ Begin
+ { it should be noted that there is no scientific basis for }
+ { the following three lines :) }
+ grid[0] := Uint32(Trunc((xbase * 14 + x*4 + xmove*sin(b)+sin(cos(a)*sin(amp))*15) * 65536));
+ grid[1] := Uint32(Trunc((ybase * 31 + y*3 + ymove*cos(b)*sin(sin(a)*cos(amp))*30) * 65536));
+ id := (cos(xbase) + sin(ybase) + cos(a*xmove*0.17) + sin(b*ymove*0.11)) * amp * 23;
+ If id < -127 Then
+ grid[2] := 0
+ Else
+ If id > 127 Then
+ grid[2] := 255 Shl 16
+ Else
+ grid[2] := (128 Shl 16) + Trunc(id * 65536.0);
+ grid += 3;
+ b += pi / 30;
+ End;
+ a += pi / 34;
+ End;
+End;
+
+Procedure make_light_table(lighttable : PUint8);
+
+Var
+ i, j : Integer;
+ tv : Integer;
+
+Begin
+ For i := 0 To 255 Do
+ For j := 0 To 255 Do
+ Begin
+ { light table goes from 0 to i*2. }
+ tv := (i * j) Div 128;
+ If tv > 255 Then
+ tv := 255;
+ lighttable[(j * 256) + i] := tv;
+ End;
+End;
+
+{ if you want to see how to do this properly, look at the tunnel3d demo. }
+{ (not included in this distribution :) }
+Procedure texture_warp(dest, grid, texture : PUint32; lighttable : PUint8);
+
+Var
+ utl, utr, ubl, ubr : Integer;
+ vtl, vtr, vbl, vbr : Integer;
+ itl, itr, ibl, ibr : Integer;
+ dudx, dvdx, didx, dudy, dvdy, didy, ddudy, ddvdy, ddidy : Integer;
+ dudx2, dvdx2, didx2 : Integer;
+ bx, by, px, py : Integer;
+ uc, vc, ic, ucx, vcx, icx : Integer;
+
+ edi : Uint32;
+ texel : Uint32;
+
+ cbp, dp : PUint32;
+ dpix : Uint32;
+
+ ltp : PUint8;
+
+Begin
+ cbp := grid;
+ For by := 0 To 24 Do
+ Begin
+ For bx := 0 To 39 Do
+ Begin
+ utl := Integer(cbp^);
+ vtl := Integer((cbp + 1)^);
+ itl := Integer((cbp + 2)^);
+ utr := Integer((cbp + (1 * 3))^);
+ vtr := Integer((cbp + (1 * 3) + 1)^);
+ itr := Integer((cbp + (1 * 3) + 2)^);
+ ubl := Integer((cbp + (41 * 3))^);
+ vbl := Integer((cbp + (41 * 3) + 1)^);
+ ibl := Integer((cbp + (41 * 3) + 2)^);
+ ubr := Integer((cbp + (42 * 3))^);
+ vbr := Integer((cbp + (42 * 3) + 1)^);
+ ibr := Integer((cbp + (42 * 3) + 2)^);
+ dudx := (utr - utl) Div 8;
+ dvdx := (vtr - vtl) Div 8;
+ didx := (itr - itl) Div 8;
+ dudx2 := (ubr - ubl) Div 8;
+ dvdx2 := (vbr - vbl) Div 8;
+ didx2 := (ibr - ibl) Div 8;
+ dudy := (ubl - utl) Div 8;
+ dvdy := (vbl - vtl) Div 8;
+ didy := (ibl - itl) Div 8;
+ ddudy := (dudx2 - dudx) Div 8;
+ ddvdy := (dvdx2 - dvdx) Div 8;
+ ddidy := (didx2 - didx) Div 8;
+ uc := utl;
+ vc := vtl;
+ ic := itl;
+ For py := 0 To 7 Do
+ Begin
+ ucx := uc;
+ vcx := vc;
+ icx := ic;
+ dp := dest + (((by * 8 + py)*320) + (bx * 8));
+ For px := 0 To 7 Do
+ Begin
+
+ { get light table pointer for current intensity }
+ ltp := lighttable + ((icx And $FF0000) Shr 8);
+
+ { get texel }
+ edi := ((ucx And $FF0000) Shr 16) + ((vcx And $FF0000) Shr 8);
+ texel := texture[edi];
+
+ { calculate actual colour }
+ dpix := ltp[(texel Shr 16) And 255];
+ dpix := dpix Shl 8;
+ dpix := dpix Or ltp[(texel Shr 8) And 255];
+ dpix := dpix Shl 8;
+ dpix := dpix Or ltp[texel And 255];
+
+ dp^ := dpix;
+ Inc(dp);
+
+ ucx += dudx;
+ vcx += dvdx;
+ icx += didx;
+ End;
+ uc += dudy;
+ vc += dvdy;
+ ic += didy;
+ dudx += ddudy;
+ dvdx += ddvdy;
+ didx += ddidy;
+ End;
+ cbp += 3;
+ End;
+ cbp += 3;
+ End;
+End;
+
+Var
+ format : TPTCFormat;
+ texture : TPTCSurface;
+ surface : TPTCSurface;
+ console : TPTCConsole;
+ lighttable : PUint8;
+ { texture grid }
+ grid : Array[0..41*26*3-1] Of Uint32;
+ xbase, ybase, xmove, ymove, amp, dct, dxb, dyb, dxm, dym, sa : Single;
+
+ p1, p2 : PUint32;
+
+Begin
+ format := Nil;
+ texture := Nil;
+ surface := Nil;
+ console := Nil;
+ lighttable := Nil;
+ Try
+ Try
+ { create format }
+ format := TPTCFormat.Create(32, $00FF0000, $0000FF00, $000000FF);
+
+ { create texture surface }
+ texture := TPTCSurface.Create(256, 256, format);
+
+ { create texture }
+ generate(texture);
+
+ { create lighttable }
+ lighttable := GetMem(256 * 256);
+ make_light_table(lighttable);
+
+ { create console }
+ console := TPTCConsole.Create;
+
+ { open console }
+ console.open('Warp demo', 320, 200, format);
+
+ { create drawing surface }
+ surface := TPTCSurface.Create(320, 200, format);
+
+ { control values }
+ xbase := 0;
+ ybase := 0;
+ xmove := 0;
+ ymove := 0;
+ amp := 0;
+ dct := 0.024;
+ dxb := 0.031;
+ dyb := -0.019;
+ dxm := 0.015;
+ dym := -0.0083;
+
+ { main loop }
+ While Not console.KeyPressed Do
+ Begin
+
+ { create texture mapping grid }
+ grid_map(grid, xbase, ybase, xmove, ymove*3, amp);
+
+ p1 := surface.lock;
+ Try
+ p2 := texture.lock;
+ Try
+ { map texture to drawing surface }
+ texture_warp(p1, grid, p2, lighttable);
+ Finally
+ texture.unlock;
+ End;
+ Finally
+ surface.unlock;
+ End;
+
+ { copy surface to console }
+ surface.copy(console);
+
+ { update console }
+ console.update;
+
+ { move control values (limit them so it doesn't go too far) }
+ xbase += dxb;
+ If xbase > pi Then
+ dxb := -dxb;
+ If xbase < (-pi) Then
+ dxb := -dxb;
+
+ ybase += dyb;
+ If ybase > pi Then
+ dyb := -dyb;
+ If ybase < (-pi) Then
+ dyb := -dyb;
+
+ xmove += dxm;
+ If xmove > pi Then
+ dxm := -dxm;
+ If xmove < (-pi) Then
+ dxm := -dxm;
+
+ ymove += dym;
+ If ymove > pi Then
+ dym := -dym;
+ If ymove < (-pi) Then
+ dym := -dym;
+
+ amp += dct;
+ sa := sin(amp);
+ If (sa > -0.0001) And (sa < 0.0001) Then
+ Begin
+ If amp > 8.457547 Then
+ dct := -dct;
+ If amp < -5.365735 Then
+ dct := -dct;
+ End;
+ End;
+ Finally
+ console.close;
+ console.Free;
+ surface.Free;
+ texture.Free;
+ format.Free;
+ If assigned(lighttable) Then
+ FreeMem(lighttable);
+ End;
+ Except
+ On e : TPTCError Do
+ e.report;
+ End;
+End.
diff --git a/packages/ptc/examples/timer.pp b/packages/ptc/examples/timer.pp
new file mode 100644
index 0000000000..1cef973ad7
--- /dev/null
+++ b/packages/ptc/examples/timer.pp
@@ -0,0 +1,116 @@
+{
+Ported to FPC by Nikolay Nikolov (nickysn@users.sourceforge.net)
+}
+
+{
+ Timer example for OpenPTC 1.0 C++ Implementation
+ Copyright (c) Glenn Fiedler (ptc@gaffer.org)
+ This source code is in the public domain
+}
+
+Program TimerExample;
+
+{$MODE objfpc}
+
+Uses
+ ptc;
+
+Var
+ console : TPTCConsole;
+ format : TPTCFormat;
+ surface : TPTCSurface;
+ timer : TPTCTimer;
+ time, t : Double;
+ pixels : PDWord;
+ width, height : Integer;
+ repeats, center, magnitude, intensity, sx : Single;
+ x, y : Integer;
+
+Begin
+ timer := Nil;
+ format := Nil;
+ surface := Nil;
+ console := Nil;
+ Try
+ Try
+ { create console }
+ console := TPTCConsole.Create;
+
+ { create format }
+ format := TPTCFormat.Create(32, $00FF0000, $0000FF00, $000000FF);
+
+ { open the console }
+ console.open('Timer example', format);
+
+ { create surface matching console dimensions }
+ surface := TPTCSurface.Create(console.width, console.height, format);
+
+ { create timer }
+ timer := TPTCTimer.Create;
+
+ { start timer }
+ timer.start;
+
+ { loop until a key is pressed }
+ While Not console.KeyPressed Do
+ Begin
+ { get current time from timer }
+ time := timer.time;
+
+ { clear surface }
+ surface.clear;
+
+ { lock surface }
+ pixels := surface.lock;
+ Try
+ { get surface dimensions }
+ width := surface.width;
+ height := surface.height;
+
+ { sine curve parameters }
+ repeats := 2;
+ center := height / 2;
+ magnitude := height / 3;
+
+ { render a sine curve }
+ For x := 0 To width - 1 Do
+ Begin
+ { rescale 'x' in the range [0,2*pi] }
+ sx := x / width * 2 * pi;
+
+ { calculate time at current position }
+ t := time + sx * repeats;
+
+ { lookup sine intensity at time 't' }
+ intensity := sin(t);
+
+ { convert intensity to a y position on the surface }
+ y := Trunc(center + intensity * magnitude);
+
+ { plot pixel on sine curve }
+ pixels[x + y * width] := $000000FF;
+ End;
+ Finally
+ { unlock surface }
+ surface.unlock;
+ End;
+
+ { copy to console }
+ surface.copy(console);
+
+ { update console }
+ console.update;
+ End;
+ Finally
+ timer.Free;
+ surface.Free;
+ console.close;
+ console.Free;
+ format.Free;
+ End;
+ Except
+ On error : TPTCError Do
+ { report error }
+ error.report;
+ End;
+End.
diff --git a/packages/ptc/examples/tunnel.pp b/packages/ptc/examples/tunnel.pp
new file mode 100644
index 0000000000..15b1815404
--- /dev/null
+++ b/packages/ptc/examples/tunnel.pp
@@ -0,0 +1,198 @@
+{
+Ported to FPC by Nikolay Nikolov (nickysn@users.sourceforge.net)
+}
+
+{
+ Tunnel demo for OpenPTC 1.0 C++ API
+ Originally coded by Thomas Rizos (rizos@swipnet.se)
+ Adapted for OpenPTC by Glenn Fiedler (ptc@gaffer.org)
+ This source code is licensed under the GNU GPL
+}
+
+Program Tunnel;
+
+{$MODE objfpc}
+
+Uses
+ ptc, Math;
+
+Type
+ { tunnel class }
+ TTunnel = Class(TObject)
+ Public
+ Constructor Create;
+ Destructor Destroy; Override;
+ Procedure setup;
+ Procedure draw(buffer : PUint32; t : Single);
+ Private
+ { tunnel data }
+ tunnel : PUint32;
+ texture : PUint8;
+ End;
+
+Constructor TTunnel.Create;
+
+Begin
+ tunnel := Nil;
+ texture := Nil;
+
+ { allocate tables }
+ tunnel := GetMem(320*200*SizeOf(Uint32));
+ texture := GetMem(256*256*2*SizeOf(Uint8));
+
+ { setup }
+ setup;
+End;
+
+Destructor TTunnel.Destroy;
+
+Begin
+ { free tables }
+ If assigned(tunnel) Then
+ FreeMem(tunnel);
+ If assigned(texture) Then
+ FreeMem(texture);
+
+ Inherited Destroy;
+End;
+
+Procedure TTunnel.setup;
+
+Var
+ index : Integer;
+ x, y : Integer;
+ angle, angle1, angle2, radius, u, v : Double;
+
+Begin
+ { tunnel index }
+ index := 0;
+
+ { generate tunnel table }
+ For y := 100 DownTo -99 Do
+ For x := -160 To 159 Do
+ Begin
+ { calculate angle from center }
+ angle := arctan2(y, x) * 256 / pi / 2;
+
+ { calculate radius from center }
+ radius := sqrt(x * x + y * y);
+
+ { clamp radius to minimum }
+ If radius < 1 Then
+ radius := 1;
+
+ { texture coordinates }
+ u := angle;
+ v := 6000 / radius;
+
+ { calculate texture index for (u,v) }
+ tunnel[index] := (Trunc(v) And $FF) * 256 + (Trunc(u) And $FF);
+ Inc(index);
+ End;
+
+ { generate blue plasma texture }
+ index := 0;
+ angle2 := pi * 2/256 * 230;
+ For y := 0 To 256 * 2 - 1 Do
+ Begin
+ angle1 := pi * 2/256 * 100;
+ For x := 0 To 256-1 Do
+ Begin
+ texture[index] := Trunc(sin(angle1)*80 + sin(angle2)*40 + 128);
+ angle1 := angle1 + pi*2/256*3;
+ Inc(index);
+ End;
+ angle2 := angle2 + pi * 2/256 *2;
+ End;
+End;
+
+Procedure TTunnel.draw(buffer : PUint32; t : Single);
+
+Var
+ x, y : Integer;
+ scroll : Uint32;
+ i : Integer;
+
+Begin
+ { tunnel control functions }
+ x := Trunc(sin(t) * 99.9);
+ y := Trunc(t * 200);
+
+ { calculate tunnel scroll offset }
+ scroll := ((y And $FF) Shl 8) + (x And $FF);
+
+ { loop through each pixel }
+ For i := 0 To 64000-1 Do
+ { lookup tunnel texture }
+ buffer[i] := texture[tunnel[i] + scroll];
+End;
+
+Var
+ format : TPTCFormat;
+ console : TPTCConsole;
+ surface : TPTCSurface;
+ TheTunnel : TTunnel;
+ time, delta : Single;
+ buffer : PUint32;
+
+Begin
+ format := Nil;
+ surface := Nil;
+ console := Nil;
+ TheTunnel := Nil;
+ Try
+ Try
+ { create format }
+ format := TPTCFormat.Create(32, $00FF0000, $0000FF00, $000000FF);
+
+ { create console }
+ console := TPTCConsole.Create;
+
+ { open console }
+ console.open('Tunnel demo', 320, 200, format);
+
+ { create surface }
+ surface := TPTCSurface.Create(320, 200, format);
+
+ { create tunnel }
+ TheTunnel := TTunnel.Create;
+
+ { time data }
+ time := 0;
+ delta := 0.03;
+
+ { loop until a key is pressed }
+ While Not console.KeyPressed Do
+ Begin
+ { lock surface }
+ buffer := surface.lock;
+ Try
+ { draw tunnel }
+ TheTunnel.draw(buffer, time);
+ Finally
+ { unlock surface }
+ surface.unlock;
+ End;
+
+ { copy to console }
+ surface.copy(console);
+
+ { update console }
+ console.update;
+
+ { update time }
+ time += delta;
+ End;
+ Finally
+ TheTunnel.Free;
+ surface.Free;
+ console.close;
+ console.Free;
+ format.Free;
+ End;
+ Except
+ On error : TPTCError Do
+ { report error }
+ error.report;
+ End;
+End.
diff --git a/packages/ptc/examples/tunnel3d.pp b/packages/ptc/examples/tunnel3d.pp
new file mode 100644
index 0000000000..ccf3c7a6af
--- /dev/null
+++ b/packages/ptc/examples/tunnel3d.pp
@@ -0,0 +1,612 @@
+{
+Ported to FPC by Nikolay Nikolov (nickysn@users.sourceforge.net)
+}
+
+{
+ Tunnel3D demo for OpenPTC 1.0 C++ API
+
+ Realtime raytraced tunnel
+ Copyright (c) 1998 Christian Nentwich (brn@eleet.mcb.at)
+ This source code is licensed under the GNU LGPL
+
+ And do not just blatantly cut&paste this into your demo :)
+}
+
+Program Tunnel3D;
+
+{$MODE objfpc}
+
+Uses
+ ptc, Math;
+
+Type
+ PVector = ^TVector;
+ TVector = Array[0..2] Of Single; { X,Y,Z }
+ TMatrix = Array[0..3, 0..3] Of Single;{ FIRST = COLUMN
+ SECOND = ROW
+
+ [0, 0] [1, 0] [2, 0]
+ [0, 1] [1, 1] [2, 1]
+ [0, 2] [1, 2] [2, 2]
+ (I know the matrices are the wrong way round, so what, the code is quite
+ old :) }
+
+ TRayTunnel = Class(TObject)
+ Private
+ tunneltex : PUint8; { Texture }
+ pal : PUint8; { Original palette }
+ lookup : PUint32; { Lookup table for lighting }
+
+ sintab, costab : PSingle; { Take a guess }
+
+ u_array, v_array, l_array : PInteger; { Raytraced coordinates and light }
+ norms : PVector;
+
+ radius, radius_sqr : Single;
+ rot : TMatrix;
+
+ pos, light : TVector; { Position in the tunnel, pos of }
+ xa, ya, za : Integer; { lightsource, angles }
+
+ lightstatus : Boolean; { Following the viewer ? }
+
+ Public
+ Constructor Create(rad : Single); { Constructor takes the radius }
+ Destructor Destroy; Override;
+
+ Procedure load_texture;
+
+ Procedure tilt(x, y, z : Integer); { Rotate relative }
+ Procedure tilt(x, y, z : Integer; abs : Uint8); { Absolute }
+
+ Procedure move(dx, dy, dz : Single); { Relative move }
+ Procedure move(x, y, z : Single; abs : Uint8); { Absolute }
+
+ Procedure movelight(dx, dy, dz : Single);
+ Procedure movelight(x, y, z : Single; abs : Uint8);
+
+ Procedure locklight(lock : Boolean); { Make the light follow the viewer }
+
+ Procedure interpolate; { Raytracing }
+
+ Procedure draw(dest : PUint32); { Draw the finished tunnel }
+ End;
+
+{ VECTOR ROUTINES }
+Procedure vector_normalize(Var v : TVector);
+
+Var
+ length : Single;
+
+Begin
+ length := v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
+ length := sqrt(length);
+ If length <> 0 Then
+ Begin
+ v[0] := v[0] / length;
+ v[1] := v[1] / length;
+ v[2] := v[2] / length;
+ End
+ Else
+ Begin
+ v[0] := 0;
+ v[1] := 0;
+ v[2] := 0;
+ End;
+End;
+
+Procedure vector_times_matrix(Const v : TVector; Const m : TMatrix;
+ Var res : TVector);
+
+Var
+ i, j : Integer;
+
+Begin
+ For j := 0 To 2 Do
+ Begin
+ res[j] := 0;
+ For i := 0 To 2 Do
+ res[j] := res[j] + (m[j, i] * v[i]);
+ End;
+End;
+
+Procedure matrix_idle(Var m : TMatrix);
+
+Begin
+ FillChar(m, SizeOf(TMatrix), 0);
+ m[0, 0] := 1;
+ m[1, 1] := 1;
+ m[2, 2] := 1;
+ m[3, 3] := 1;
+End;
+
+Procedure matrix_times_matrix(Const m1, m2 : TMatrix; Var res : TMatrix);
+
+Var
+ i, j, k : Integer;
+
+Begin
+ For j := 0 To 3 Do
+ For i := 0 To 3 Do
+ Begin
+ res[i, j] := 0;
+ For k := 0 To 3 Do
+ res[i, j] := res[i, j] + (m1[k, j] * m2[i, k]);
+ End;
+End;
+
+Procedure matrix_rotate_x(Var m : TMatrix; angle : Integer; sintab, costab : PSingle);
+
+Var
+ tmp, tmp2 : TMatrix;
+
+Begin
+ matrix_idle(tmp);
+ tmp[1, 1] := costab[angle];
+ tmp[2, 1] := sintab[angle];
+ tmp[1, 2] := -sintab[angle];
+ tmp[2, 2] := costab[angle];
+ matrix_times_matrix(tmp, m, tmp2);
+ Move(tmp2, m, SizeOf(TMatrix));
+End;
+
+Procedure matrix_rotate_y(Var m : TMatrix; angle : Integer; sintab, costab : PSingle);
+
+Var
+ tmp, tmp2 : TMatrix;
+
+Begin
+ matrix_idle(tmp);
+ tmp[0, 0] := costab[angle];
+ tmp[2, 0] := -sintab[angle];
+ tmp[0, 2] := sintab[angle];
+ tmp[2, 2] := costab[angle];
+ matrix_times_matrix(tmp, m, tmp2);
+ Move(tmp2, m, SizeOf(TMatrix));
+End;
+
+Procedure matrix_rotate_z(Var m : TMatrix; angle : Integer; sintab, costab : PSingle);
+
+Var
+ tmp, tmp2 : TMatrix;
+
+Begin
+ matrix_idle(tmp);
+ tmp[0, 0] := costab[angle];
+ tmp[1, 0] := sintab[angle];
+ tmp[0, 1] := -sintab[angle];
+ tmp[1, 1] := costab[angle];
+ matrix_times_matrix(tmp, m, tmp2);
+ Move(tmp2, m, SizeOf(TMatrix));
+End;
+
+Constructor TRayTunnel.Create(rad : Single);
+
+Var
+ x, y : Single;
+ i, j : Integer;
+ tmp : TVector;
+
+Begin
+ tunneltex := Nil;
+ sintab := Nil;
+ costab := Nil;
+ u_array := Nil;
+ v_array := Nil;
+ norms := Nil;
+ lookup := Nil;
+ pal := Nil;
+
+ radius := rad;
+ radius_sqr := rad * rad;
+
+ sintab := GetMem(1024 * SizeOf(Single)); { Set trigonometry and lookups }
+ costab := GetMem(1024 * SizeOf(Single));
+ u_array := GetMem(64 * 26 * SizeOf(Integer));
+ v_array := GetMem(64 * 26 * SizeOf(Integer));
+ l_array := GetMem(64 * 26 * SizeOf(Integer));
+ norms := GetMem(64 * 26 * 3 * SizeOf(Single));
+
+ lookup := GetMem(65 * 256 * SizeOf(Uint32));
+ pal := GetMem(768 * SizeOf(Uint8));
+
+ For i := 0 To 1023 Do
+ Begin
+ sintab[i] := sin(i * pi / 512);
+ costab[i] := cos(i * pi / 512);
+ End;
+
+ { Generate normal vectors }
+ y := -100;
+ For j := 0 To 25 Do
+ Begin
+ x := -160;
+ For i := 0 To 40 Do
+ Begin
+ tmp[0] := x;
+ tmp[1] := y;
+ tmp[2] := 128;
+ vector_normalize(tmp);
+ norms[j * 64 + i] := tmp;
+ x := x + 8;
+ End;
+ y := y + 8;
+ End;
+
+ { Reset tunnel and light position and all angles }
+ pos[0] := 0; pos[1] := 0; pos[2] := 0;
+ light[0] := 1; light[1] := 1; light[2] := 0;
+
+ xa := 0; ya := 0; za := 0;
+
+ lightstatus := False;
+
+ { Normalize light vector to length 1.0 }
+ vector_normalize(light);
+End;
+
+Destructor TRayTunnel.Destroy;
+
+Begin
+ If Assigned(tunneltex) Then
+ FreeMem(tunneltex);
+ If Assigned(pal) Then
+ FreeMem(pal);
+ If Assigned(lookup) Then
+ FreeMem(lookup);
+ If Assigned(norms) Then
+ FreeMem(norms);
+ If Assigned(l_array) Then
+ FreeMem(l_array);
+ If Assigned(v_array) Then
+ FreeMem(v_array);
+ If Assigned(u_array) Then
+ FreeMem(u_array);
+ If Assigned(costab) Then
+ FreeMem(costab);
+ If Assigned(sintab) Then
+ FreeMem(sintab);
+End;
+
+Procedure TRayTunnel.load_texture;
+
+Var
+ texfile : File;
+ tmp : PUint8;
+ i, j : Uint32;
+ r, g, b : Uint32;
+ newoffs : Integer;
+
+Begin
+ { Allocate tunnel texture 65536+33 bytes too big }
+
+ If tunneltex <> Nil Then
+ Begin
+ FreeMem(tunneltex);
+ tunneltex := Nil;
+ End;
+ tunneltex := GetMem(2*65536 + 33);
+ tmp := GetMem(65536);
+
+ { Align the texture on a 64k boundary }
+ While (PtrUInt(tunneltex) And $FFFF) <> 0 Do
+ Inc(tunneltex);
+
+ ASSign(texfile, 'tunnel3d.raw');
+ Reset(texfile, 1);
+ BlockRead(texfile, pal^, 768);
+ BlockRead(texfile, tmp^, 65536);
+ Close(texfile);
+
+ { Generate lookup table for lighting (65 because of possible inaccuracies) }
+
+ For j := 0 To 64 Do
+ For i := 0 To 255 Do
+ Begin
+ r := pal[i * 3] Shl 2;
+ g := pal[i * 3 + 1] Shl 2;
+ b := pal[i * 3 + 2] Shl 2;
+ r := (r * j) Shr 6;
+ g := (g * j) Shr 6;
+ b := (b * j) Shr 6;
+ If r > 255 Then
+ r := 255;
+ If g > 255 Then
+ g := 255;
+ If b > 255 Then
+ b := 255;
+ lookup[j * 256 + i] := (r Shl 16) Or (g Shl 8) Or b;
+ End;
+
+ { Arrange texture for cache optimised mapping }
+
+ For j := 0 To 255 Do
+ For i := 0 To 255 Do
+ Begin
+ newoffs := ((i Shl 8) And $F800) + (i And $0007) + ((j Shl 3) And $7F8);
+ (tunneltex + newoffs)^ := (tmp + j * 256 + i)^;
+ End;
+
+ FreeMem(tmp);
+End;
+
+Procedure TRayTunnel.interpolate;
+
+Var
+ ray, intsc, norm, lvec : TVector;
+ x, y, a, b, c, discr, t, res : Single;
+ i, j : Integer;
+
+Begin
+ If lightstatus Then { Lightsource locked to viewpoint }
+ light := pos;
+
+ matrix_idle(rot);
+ matrix_rotate_x(rot, xa And $3FF, sintab, costab);
+ matrix_rotate_y(rot, ya And $3FF, sintab, costab);
+ matrix_rotate_z(rot, za And $3FF, sintab, costab);
+
+ { Constant factor }
+ c := 2 * (pos[0] * pos[0] + pos[1] * pos[1] - radius_sqr);
+
+ { Start raytracing }
+ y := -100;
+ For j := 0 To 25 Do
+ Begin
+ x := -160;
+ For i := 0 To 40 Do
+ Begin
+ vector_times_matrix(norms[(j Shl 6) + i], rot, ray);
+
+ a := 2 * (ray[0] * ray[0] + ray[1] * ray[1]);
+ b := 2 * (pos[0] * ray[0] + pos[1] * ray[1]);
+
+ discr := b * b - a * c;
+ If discr > 0 Then
+ Begin
+ discr := sqrt(discr);
+ t := (- b + discr) / a;
+
+ { Calculate intersection point }
+ intsc[0] := pos[0] + t * ray[0];
+ intsc[1] := pos[1] + t * ray[1];
+ intsc[2] := pos[2] + t * ray[2];
+
+ { Calculate texture index at intersection point (cylindrical mapping) }
+ { Try and adjust the 0.2 to stretch/shrink the texture }
+ u_array[(j Shl 6) + i] := Trunc(intsc[2] * 0.2) Shl 16;
+ v_array[(j Shl 6) + i] := Trunc(abs(arctan2(intsc[1], intsc[0]) * 256 / pi)) Shl 16;
+
+ { Calculate the dotproduct between the normal vector and the vector }
+ { from the intersection point to the lightsource }
+ norm[0] := intsc[0] / radius;
+ norm[1] := intsc[1] / radius;
+ norm[2] := 0;
+
+ lvec[0] := intsc[0] - light[0];
+ lvec[1] := intsc[1] - light[1];
+ lvec[2] := intsc[2] - light[2];
+ vector_normalize(lvec);
+
+ res := lvec[0] * norm[0] + lvec[1] * norm[1] + lvec[2] * norm[2];
+
+ { Scale the light a bit }
+ res *= res;
+ If res < 0 Then
+ res := 0;
+ If res > 1 Then
+ res := 1;
+ res *= 63;
+
+ { Put it into the light array }
+ l_array[(j Shl 6) + i] := Trunc(res) Shl 16;
+ End
+ Else
+ Begin
+ u_array[(j Shl 6) + i] := 0;
+ v_array[(j Shl 6) + i] := 0;
+ l_array[(j Shl 6) + i] := 0;
+ End;
+ x := x + 8;
+ End;
+ y := y + 8;
+ End;
+End;
+
+Procedure TRayTunnel.draw(dest : PUint32);
+
+Var
+ x, y, lu, lv, ru, rv, liu, liv, riu, riv : Integer;
+ iu, iv, i, j, ll, rl, lil, ril, l, il : Integer;
+ iadr, adr, til_u, til_v, til_iu, til_iv : DWord;
+ bla : Uint8;
+
+Begin
+ For j := 0 To 24 Do
+ For i := 0 To 39 Do
+ Begin
+ iadr := (j Shl 6) + i;
+
+ { Set up gradients }
+ lu := u_array[iadr]; ru := u_array[iadr + 1];
+ liu := (u_array[iadr + 64] - lu) Shr 3;
+ riu := (u_array[iadr + 65] - ru) Shr 3;
+
+ lv := v_array[iadr]; rv := v_array[iadr + 1];
+ liv := (v_array[iadr + 64] - lv) Shr 3;
+ riv := (v_array[iadr + 65] - rv) Shr 3;
+
+ ll := l_array[iadr]; rl := l_array[iadr + 1];
+ lil := (l_array[iadr + 64] - ll) Shr 3;
+ ril := (l_array[iadr + 65] - rl) Shr 3;
+
+ For y := 0 To 7 Do
+ Begin
+ iu := (ru - lu) Shr 3;
+ iv := (rv - lv) Shr 3;
+ l := ll;
+ il := (rl - ll) Shr 3;
+
+ { Mess up everything for the sake of cache optimised mapping :) }
+ til_u := DWord(((lu Shl 8) And $F8000000) Or ((lu Shr 1) And $00007FFF) Or (lu And $00070000));
+ til_v := DWord(((lv Shl 3) And $07F80000) Or ((lv Shr 1) And $00007FFF));
+ til_iu := DWord((((iu Shl 8) And $F8000000) Or ((iu Shr 1) And $00007FFF) Or
+ (iu And $00070000)) Or $07F88000);
+ til_iv := DWord((((iv Shl 3) And $07F80000) Or ((iv Shr 1) And $00007FFF)) Or $F8078000);
+
+ adr := til_u + til_v;
+
+ For x := 0 To 7 Do
+ Begin
+ { Interpolate texture u,v and light }
+ Inc(til_u, til_iu);
+ Inc(til_v, til_iv);
+ Inc(l, il);
+
+ adr := adr Shr 16;
+
+ til_u := til_u And DWord($F8077FFF);
+ til_v := til_v And $07F87FFF;
+
+ bla := (tunneltex + adr)^;
+
+ adr := til_u + til_v;
+
+ { Look up the light and write to buffer }
+ (dest + ((j Shl 3) + y) * 320 + (I Shl 3) + x)^ := lookup[((l And $3F0000) Shr 8) + bla];
+ End;
+
+ Inc(lu, liu); Inc(ru, riu);
+ Inc(lv, liv); Inc(rv, riv);
+ Inc(ll, lil); Inc(rl, ril);
+ End;
+ End;
+End;
+
+{ tilt rotates the viewer in the tunnel in a relative / absolute way }
+Procedure TRayTunnel.tilt(x, y, z : Integer);
+
+Begin
+ xa := (xa + x) And $3FF;
+ ya := (ya + y) And $3FF;
+ za := (za + z) And $3FF;
+End;
+
+Procedure TRayTunnel.tilt(x, y, z : Integer; abs : Uint8);
+
+Begin
+ xa := x And $3FF;
+ ya := y And $3FF;
+ za := z And $3FF;
+End;
+
+{ Relative / absolute move }
+Procedure TRayTunnel.move(dx, dy, dz : Single);
+
+Begin
+ pos[0] := pos[0] + dx;
+ pos[1] := pos[1] + dy;
+ pos[2] := pos[2] + dz;
+End;
+
+Procedure TRayTunnel.move(x, y, z : Single; abs : Uint8);
+
+Begin
+ pos[0] := x;
+ pos[1] := y;
+ pos[2] := z;
+End;
+
+{ Relative / absolute move for the lightsource }
+Procedure TRayTunnel.movelight(dx, dy, dz : Single);
+
+Begin
+ light[0] := light[0] + dx;
+ light[1] := light[1] + dy;
+ light[2] := light[2] + dz;
+End;
+
+Procedure TRayTunnel.movelight(x, y, z : Single; abs : Uint8);
+
+Begin
+ light[0] := x;
+ light[1] := y;
+ light[2] := z;
+End;
+
+{ Lock lightsource to the viewer }
+Procedure TRayTunnel.locklight(lock : Boolean);
+
+Begin
+ lightstatus := lock;
+End;
+
+Var
+ console : TPTCConsole;
+ surface : TPTCSurface;
+ format : TPTCFormat;
+ tunnel : TRayTunnel;
+ posz, phase_x, phase_y : Single;
+ angle_x, angle_y : Integer;
+ buffer : PUint32;
+
+Begin
+ format := Nil;
+ surface := Nil;
+ console := Nil;
+ tunnel := Nil;
+ Try
+ Try
+ format := TPTCFormat.Create(32, $00FF0000, $0000FF00, $000000FF);
+
+ console := TPTCConsole.create;
+ console.open('Tunnel3D demo', 320, 200, format);
+
+ surface := TPTCSurface.create(320, 200, format);
+
+ { Create a tunnel, radius=700 }
+ tunnel := TRayTunnel.Create(700);
+
+ tunnel.load_texture;
+
+ { Light follows the viewer }
+ tunnel.locklight(True);
+
+ posz := 80; phase_x := 0; phase_y := 0;
+ angle_x := 6; angle_y := 2;
+
+ While Not console.KeyPressed Do
+ Begin
+ buffer := surface.lock;
+ Try
+ tunnel.interpolate;
+
+ { Draw to offscreen buffer }
+ tunnel.draw(buffer);
+ Finally
+ surface.unlock;
+ End;
+
+ { And copy to screen }
+ surface.copy(console);
+
+ console.update;
+
+ tunnel.tilt(angle_x, angle_y, 0);
+ tunnel.move(sin(phase_x), cos(phase_y), posz);
+
+ phase_x := phase_x + 0.2;
+ phase_y := phase_y + 0.1;
+ End;
+ Finally
+ console.close;
+ console.Free;
+ surface.Free;
+ tunnel.Free;
+ format.Free;
+ End;
+ Except
+ On error : TPTCError Do
+ error.report;
+ End;
+End.
diff --git a/packages/ptc/examples/tunnel3d.raw b/packages/ptc/examples/tunnel3d.raw
new file mode 100644
index 0000000000..774b845379
--- /dev/null
+++ b/packages/ptc/examples/tunnel3d.raw
@@ -0,0 +1,217 @@
+ 1$
++7*$(.!4'7/$ " (.+=(!7!:%1"
+ =,$3&9,#*$ - !
+9( 0 -!3! #0#"1#"( 4&%91&.  7)( ?)&<&#%+!#80%*/,2  =++#9# "0&$9+*   ,)  /"8' ='):$&
+&5$ ;*")  >,(<*&)$+"! 9''!)4"##:-'.+>(%8"!;%" 1' 6$ $
+ '6$$ +( . 7%!"
+ (=+'9,&*-!
+9'##0-!3!!&0"!#2$#+! 8&&</);)) ?(*<%'&:.(*/,2  >,,#9"$ ,)  /! 8&" 5#;)%  "4":($:-$1."='$7 ":$!4$
+ 6%' "30$6  %% + 7%%/!:((?'&?$#%.#;.%2/5 ?)+& <! $3%$<**0ʜ,{{ur˞.}ƈ𰇽t_i{{{uggqFFDtVFËɾ{7xx?Mw~qʳzFqÜ
+z'~Ӌ~x̭xxxxxxxӦqީH!ە«[GHĈ޾{uzw,q~]?x]MMq{tz~~q,"Uut{k...cH-}(uo91{gIg~FzUVV'7j{q7x?]ø,z0qYz'w~~]~~x?xxx??Ӌqr˵Gl€=޾ɔ˩r{ʜwq]]ӂ𷾷tz~xx]~wq*EtUV Ğ..H-}˩(čd{h{i1_{{"ggg,z'*EtU,q~Yě{zqm\?q~qFzYz"'zF,M?M~xӋMMqqީH}«:HĔr˞..ֽ,,qÂq𾷾@v\q,'ttt...˞˞}G||}J𮁽on{uőgÜFDtVUzF,q~"#ˍ𽼊q<xw~qÜ
+"zYzD,w~wqw~]~ӂMMqqzɡ[|T_r{rHHĈ{F,FEzFqMqz#@rwqvg>v\?]]qq"U'DD.... ||J({{{ޤ{{{VggŖ,F'F,qÂ~qDƷ{z,,qMmѦ~q~~qz'
+',ʂxq~~ӋMwq,z.}-|=Tľr{{{H-ֆUF0Y
+{{tD,q~F{@07g>g>gv\v\?qʳ
+U""Ute..J}:|Tcޔd{{{orik{{U3Ŗ'DDU
+0qʂ"Eø]m?,qÂʳU
+Dt'Fq~xm],Â~~~~qʜĩ.H}T|TT:ˈir.-G}Ĕ{FF'E{d*,~qVVֆ mѪgggg>gv>̭qF"D'''{ H.˩;.JG=.{֮웈r{֒~,z'D",qq~MÜ{㛮,]x?Ѧ~,,qÂF"V*tq'z,qwwqF.}-G: }H޾G:H֒"Y
+{{"~q0UUY <gggg>>\\q0'D'"WHH.˞cTH˔{{ޙrY~w,z'zFqq~Mꋦ*dˍ~m]x?\xqFFÂó"DDV̪w՘'F,qqʜ,z.c}}:˙{J|-ľ{z,'*~ʠz
+"UsŐgggggŦ~q0Ut'F.˩ĩJ.c=˷trޛֽUYq~q~qq,Fqwxtmvv?????~qFzzF3âqztYqmvIы,D'zFqqqqFY{.HHcH.޷{-Q=Hľ֒zFttt'z"
+"<ggsgs͑ggggvmq'*
+U+.ę..cH :[HֽF,,,,,,Y
+
+,qÂM~Uޮ
+???x~q,F'zʂqq
+tt{uVqgg?qDD'zF,qʜz'{..J޾𗇽{1QQ˾{,z'tt'"sgggggmq"{{rĩHH}[=G.z{1E*Dw~xʓķqvvv??M3,'Dqqt{{V̋,*DFF
+{ɤƩĈ_{.[˾z"{{{{{uFFfsgsggggmʓ@utޙ˵H:=:r,rr{UtEEEu{{q?xó{.ޮggv>\xMqDzY{@𮚳>gq'*DzFzz'𾍙ĩލ{h_:|[[=˷rzFt{i{{âsggsg>>mqtr{t(H}GGHqqU{{'z'z'tu{dr{'~x?qV3g>>vіMqzDDtz{{֮dqgŪ,ttzzzr𔾍ޛ{tt{r=!-"zkީ.HHˍ{3qgg>>̖qF𷍛{H-}-TG-;Aq,Yzttz,33FĈ,~?~Dɼ g>v>?]ótttYzu{dgg"*EVtzz''ɷ𮇽o{T=-.rz'tƩH-GQuÜőggggv>>v\xM'rinn_u9oiީGT::G޽~qzzzq~qq{Ë?{<g>v?x~tV**𾾷u7FuEtt'UU֮r{t.-l-Jztc-: ::T=:qzʖggg>gv>vvxzɷ{o.G:}:-:HqDtzz
+tFqm74Ɉ,~?*LWg>>?w,VV*tz~gDCt'U_rևt.:=!=-.rtu.GQ==TTc(oqd*Fgg>v>>vv\]x{Ɉވ{;T€T} -3zu
+
+F~~ʓɍ{U~x~01gv̋tD'{{+ޛzzUVuuU"zzi쵝-˷{
+ ==[=T.(ֆ7ʱCEg>bvbvgvv>?]Ü{kr{{{JG!!«cT㷆ddUVVE*D',~0֮DӖxƩ{F>>vv̖~F4𔾛aޔqgt{C{ttt"
+zY_˨T=˷{;TTTTTJ{q *æ\gvvvvvvxӂózrr{{{{ɍlGc-.{ڲ
+u{{{r@@ ɮY3qqtV'q'r1E>v?qUVtt{{ޛĈu<u{{{utUtDYYziŽQķ{H cJccHH.3%??Ӌ~{rr{{{X6 (H{Ʒ,{{𷷍aaK@"q0q?~,Uޡg>v?~FVUutu{{̪Dd{{EtU''z0qYz
+u_n}G[Q|H((;;HHލɇYqYtËm?xxx]~ʜ
+V{rĨl¹GGĈH}˔ڱq~wʜ*{HcH .޾wqFq??D_FŐvxq'FY{{{uu{{𔷾ďq<7u{{uzzqt{˞=[-.𽼓d1kƩn{F'~Ӌ~~M~MMxÂqʠ
+{ㅎ--Hkrk.H.{?mÜYzUtJ.c:-:Hqw,~]~,qggv~MF,3ʠ
+֮uu{{d.t~7qD{{{{{u*'z3qqq0z"{_L G…G}ľtܮnޙ0~?ӂ~wqÂ~q0,,YU{-$G}-Hɇn.־FvvwFD{˵c :cqFq]xÜ'{gvqqFz'z~óU֮և{{{{kĞ˩ʢ
+{{{{{u{{qqq3t}T-{di_{iޛ10DѦ,,qF,F
+"U{i.|•HHH.rɈ..r{,m>gі~ʳD{_𾈙;c:T-tqMV{և3,qq,w~"{r{{{r_r.Ez,t{{{{{uz,q3t{Ğ|:}.{ցLķUqF\?~w,FFFFzzU*tU˨=}J..H.o˙rɷ{Fmvv>g>̖q,}:G.ֆ,0Ü'VU>góʂq~qMM~ʊrrrɾ..ĈD
+U{{{1LH}:T|-.ķɇ{{{֮ɾ{\wq,FFFz''u{CdV{ĵۿ.;.˷r5'v>g>gvvmq,kJƔF,DtVÛ,DzFqꋂM~~"i.숔{ED֮{{{{{{{t.c:T}.ɇ{{{ɔ1"qógvxMFF'Dt{ވH[X.}.r{krrʖg>gvgŖq,ztEޞG:.rVYFFDV*
+Ëvq'*]~wqFĈrDz
+{rr{ĩ˞H} :˙uu{{֗𔾔Ĉq~,Iv?~w3,'*HnH=X…J--Hru{rUvg>gvvmqqFzɾc}HYt*̪gvm~tEut"qmm?~wq,
+U{ɮ֒0YzzFdH} }:-}H썔{ɔk(޾{~qF>vӂ0'{-G==:} H}-[$ę(ޙ.}G-ɇ_o{ "x>gvgvM~`,z'uHVUz"t*F7v>gvʘ?m\]qʜFFz"D*{utqmqFz't{ޛܔީ.}-{{{{ވ_{zqF\>]~3,
+D*Hێ!|GG|[=5(-GHޔu_{ F]gvg>?x ~àzˈU*D<>>?~UEq\̭Ü,F3Y
+Fgg,zDUt{.čkޙީ˞J }}r{{uYqzv3,Dt{.-«Q|Q[ .˵G}.r__{#W#Ku*w\>v?x qztuKV4D,qgg>>v?'E{{Fq]xmq,3~ꖪvg<mm\\v\xz'qzɾ....ވkk.-H{ud{{q,zí>ŭ]ʜ
+"t{.=G[:Jkc--r{_i#auDFӖ?xx `~qqqztUUUF<s>gvxwu]?mqqÂvggPgPŪŪg>]MʘtDFqq7<ꢠɈ..跾iܔ5ީ˞G-ˍ{oudroÜ'?g\ӂ,zDɷc:GG-: rɛ-ˈ{{u{i1ĩqmmʜʜ,qqq'',ggggz{rr{zq 7xww<sg>>>gvv>vvіxʜz,q~?ꜱ˩ę{rrkĞTG-ķr{**{r{{{{{utzqFq\̭~q,"trJJHص.c -ɮL޾ɇV{跡n˞ˍ,ӂqFFqqqqzuF,~gggggmʊ{rr{h3]m??%?>vv?x~øqq,qqq~і]˩ĩrցr.-Qrև{r_r{ևVqDq~]mx]~qFz'{ĩ1ީ..ľrև4tVV{Ɉ˩ޙ.˛Vz~ʜDqqʂ3FÂPm{ih"]x]7 wMg>gv>v?~qqq,,q~xm~qzĩ{kĞ =[-.{*r{DzqzqꋂʜFk;J..r4UUևrL.qó'tDzFqqqqzF,ʋ̐g0Eu{r_d,~?]ÂqF~xb>vvv>v?qqq,Fz,z_ީ޷{k.=Ž[G}ޔ#r{V{_ɮz,qqʊt'zqw0Fz'{{5˙֔{"t{{rɾH}cHc F~qtEtqø~qgÊEu{ɔnq]qqYDDF?b>gvbv>vі?M~qq,''"'z"{1uV{ީH$-ޔɮ{{UFqâttt'zq,,,,Fzrr{ˈɮ.{
+AUt{HTGƷʂ,{'~0ɇ'F~̖~"VE Fqxqq'Fwg>>vvv>v?x~qqUUtɮ{tt{rĞ=$H{_{
+q~q,tt
+,YY,,,Fz{{{.˛.A
+"'J=T}.ķDFwx~VzqꂢqV{𾾈ީĩ.č@qqF,~̐>>gvv>v̭]~qFUUV{tzz.}-•$ ę{{z,qwq,Dtz
+YF,ʜ,qʠr𮮁.}.
+
+'*@ɾ.=T}.@z?àDK'~,F**Vu{ީ..V0zz'FÖg>v>>vvv?~qqzUV{{r{tqqFHŽTco{{zqø~qʳ
+*DzFF,,qqFu{{@舵-H˛qq
+"zztɮ(cT=[QT.0VqmqzVqt{r舩..HH.r4EFqgggvvvvv\vm?mx~q,
+V{{~qtH-[$¹}cuhuu'zF,qM~M~qF*,q~~qà֮;G-č{q3zYzcT[….ʼu{Fq]qÜ{dVYzDE*t*rk..H}Ĕ{utgsggvv?]~3Yz'{{z\vmq,z'{c…TTutzz,qÂMFDt*t"Ëqʳ"V1ˌ[H޷qqD
+F(c-=-Ʒ{,qÜ,#{tUt_˞} -armŐsvv\і?]~q,zV@{~>g>m~wʳYz{c :G:=oFqwMӋMq,*'z?mx~qY{G$-.ވrqD,,"t{k( G-0t{ÂÜFFɷ dtUuVUt{iީ˵H}:GG-Hވtgssvvvvі]q,'{>>>?q,
+{;;c }-[|_ozFqʂ~ʜFUtqx?vv̖xÜ𤍙‰ȿވ{ꜱCu*FtH-G؛{YEFqʳFzz
+r{zt𔍙˞.} :|GG cJ޷*~\gvvvv\\?]~wqFz'tEV{uDzæ>g>\~w,,Fz'{(˵HT.𽽽V'zFFw~?~Ü'qvv]q,'_n}[|}.ޔV՚duqʳ
+*{ޙ.T|GH*
+0z"z''"z{zin.H}GG:-ccƍggvvvm?]qʜFzD*V,q>gvvxʜFFFJ=X_o,q~x???mÜ,qw?іxMʜ'*ީ‰^y…rʱCdqꋋqn.|G{z
+z"U"z#֒o_L}T|GTT .˛Ewggv\??]]~wqFt*htzq\>gvʳz'k˵[X|oV
+zF,qvvvvvm]]]x?xMqF{{k쵻^ycľ7]t73F.H}G}ɒF""t*t"{@u*"{kƞH-||TT:Hu?gsvvѭxӂwÜ,'EDF~̪>vvq''DDUUJXX-kjU4"F,q~>>g>>gv?]~q,{{R[K, YPgggG㍰zz*{u4{.}}T}r<>>?m?x~qqz'F,M̋qqr5cŽl|ޒ*EtFYF~xvgbgggggggvqwʜ,z'@[^ @7dF<gsggmʳč {zt9t{tuV4u4{i.:G "7>g??x]~qʜ4zFq~?bvxt{{{rɾ;|_zF,q?vvggbgg\ұ't{HX [cYC<fgggŖqUFqÜUto{{{tV{d{uriƞ. …˷>>ѭxxMqwq,zzDVUY
+zzʂxvv̖~F{r_H:|ۻɼ3Ü"tt'Fvgm~qz@dddCީ.}:c* DdqIsgggg>gg7q,zz"DtE{d_{{{{֟d1˞H}:T««}އv>g̭Ӌ~ʜzzU
+âq0q~xxF{ra.G˗,*tDz,q v>vggg̖q,udޛލޛn.=[[-H˷'~mq'mIggg>b>g>>gg0,''* 1irrV{dɔ˵H}T=«T.~vŐŖӂwMq,qFFz''zF,xMq]x??F'"DUtrH-..{~ʳFmg>vgggq,d𷍛.H.LH}:T|Q:.ƙ,'VgIggg̖%?v̖q,zUtECK޷r{r.H} }:Ž«…..vgvq,zFq~ꖪ>g>іqqMꖭіxwFzz
+zY𔷍e..޾r47~YDqg>vvg>gC.H}-}H.}-TTT-H˩ޛ{~~*E,gg,,F,,MӋꋂʠ0Y{.}-}.쩈kɔֽޛɇ{ީĞ..H}:QH{z~ggvM,,FFFFgg>v?qwŭMF,,Â~
+"V@  7̖?xٜ'zFőg>>gvF{kĞJ}-}}---Hcęu*gsg̖`F''DD'w~qàF"tu.-G|GH.ވ޾{{d..HH«}ƮUqxvŪ>FFgs>vqq]\x~,qMꖖ7 
+<7<vbqYq~7ggg>>v~,{{_Ɉ5(:TTT: J޾CFgsgŖ,YY'zzz{쵌=H{ƈ.HJc:|Ž«G˛{>]~FFFssssgbb,Ӗv?~qqvvggg̖Ââmgg>v,~]gggg~DtVr;.JH-GG|-Jrt\DŐsgM'zzzzDu_ɡc}:T|[QJ޷r{ޮu{...HHc•[ ÂŪg>g~FzFF̑sͯsb]zvv~mvvggggggŪ<<<>>?,wqMgggg>?q{rީH.c} TT=(r{{d"qssgg̖qzzUhc}˙蔗{˞.c:|$…QH.mggv,z
+Fs sBs͑̂F,M>g̖ggggggg>Iggg>g\>>v>0qMggg̋zU֔.ccHcHG|TT[Gr{m,sgsggggv<77qq0q3q377qok}=Jiɽ˷֒u{;;.c}….{zꖪggvgz'zFssssBB B͑wqvggvŪggsg>g>>Ū>v>>vg>x,ʂM]xggőg>m~'D.}-HHHHTr{V '*gssggggmwËmvmq{˵Ž[ֈ..r{𔈈J.Hc-QX[H~gv?qF~ sB ͑g>gggőgs sss͐gg>gvv>v>>>>gvʠq~?gőggz""r˵T..G|=|TGcľɇ{@d gDts͐gggv]]]]]mŪvgvÜo1ĵ[ęև.u{𷈈JJcH}|Ž«L.ƷËvgg
+,ss s s Bssg>ggggggP s s s͑͑gggggvvv>>v?~,,3?]vggg~q
+'H-T|.=TTTH֟V7qss͑͑sgggg>>vv??v>v>g>>>>?ػŽ|.{.ƍ{{{JHcHc}-! ^».ě~gggq"zgsssP s ssggggggss BBs bgv]xxv>Ü0q??>ggg q0"˵-|=-޾1˵=TT=ľևFqŐsssgggv>>>>vvvvvvv>vFC+Qę{.ˍ{{ɷ(HcH}}:y=}˙,ʦggg\z'zwŐs P sbgss BBB BB b?MMx?\>vx~FFæ?mgggg~qF"zU.|c ::-}ևrdEvt0ssgggggggv>>g>>v>>>xqztu.=Ž«c1_Ĕr..HH :::[$X^^y^»1_z,mvv>vgx,
+YʖPPssssssssg͑ssB ssggggv?qʜFqqqq?v>vg,F
+| ;@rcG- J-.r*?Dʑsssggggggg>g>b>>>g>bv]~Ftu[«:__숔rɔ..c:G=[$^yy^˙{zʋvgv,'
+Ögggsgsssssggss s B B sssggvgv,'z,q~~qzzx>>>\FFFY_1LT.-|GęH}kDMD~s͑gggggggggvv>v>b>gvvv?xʳ:«Ĉi˛𔷍ĩ˵H:^^yyTctF>F0wsgs ͑sgs͑s s Psggggv\ӂtqqF'?v>>vqF,F쵴|(@ַĩH-GHĤɈn˞˙ɰզ, ssssggggggg>gvvvvvb>gv]Mq.-T=«=._ցɡޙľHHG[^yy^¨r置Vʂx,,0qxősBsssggss sB B ggggqF"t*tFqM?v?~qYL}|J;{V.}.4tFmfgssgggggg>gv>>vgg>gvv]q{HT:cľ{{ɷ.•XH.č{𷷮,?qqꋂMqősssgs s sssPsgvmxʳuDz"UzF~x???qq״({{ɼ4{k{æM'D,ss͑sggggggg>vvvvvg>іxw,zD{ĵH T:o֮ɮ1˵HŽT}.ġ{~wqÂw~w,,FFF,̑ ssgs P g?x~'U"~x~qqܾ-}.޾{3O{qq'ggsgggggg>v?m?vі]ÜzHH}Hˈr{{{{{@{{ .H}޾K޾rFqqqwø~wqz''zsgssgxw'{{{VUFYw~~~wq{JTGH޾{tt{37ooqFD~gͯsgsggg>gvv]xӦіxMq{ޛɗ{{{@r{{ޞ.c.Ĥ𗮮{.{FqӋMqҜz''z't*sgggbgs͑g~wq,{{U"zFq~~~wÜzt(cT.ɮzz{{qF'D,ssgggg>vxӂ~qÂÂ~ꋂqt𷷷{EVV@{qq,Y"..Hčɇ.޾tz,~~ʜFz'zD
+gggggŐgggv?]wt{rVttD'zF~~qʳz_c:ˈuqquu𮇽Fz'~fgs͑sggg>v??M,,qwwq,֮rɮr{*t{{"qâʠ
+U֮kkr{;H.{D~wʜ'tDz'uV*",gf>g>vvggіӂ'trD'',qm~q'9u=Tޔ{m"Ud{utFFsssggg\xwóFzzFzztDDDUDV{{""Y03030Y{{{.ވ(.:-ˍtzqq*{{tggggvvgggg>m]qztu{'F,F,q~7,˨c˷ɮ<tC{z,~ŐgssggggqzUD'"'Dtz'DDC{VU"{{.GH(H-G❵{t"0K𮽆{rd*,qm̬gvm?ӂwʳD{𡈛ʂꋋ~~qqâqʊtT ވ_r~q""VtzzFsssgsgv\w,*tz"zzFF"DtG--čr{{{֮Ɉ-QT:c.-|}Ĥr{Yčrև{
+mm̖~qMqq1޾ʦvvmqY
+V.---.k{{_qFtUzz,xsssgg?m,՘DuuVtz,,qq3qqq,zDtrHQ!ll!Q-ěrrQQ=J˩J..č {AU؞k{@ڮE'Fq~~q~wqqzt_ލ{YqgÜFz'{˞(kևi{Uz,U"@{D'~Ŭsssg̭~q,z'{{և{{{{uzqqqÂ~~FFz{ɔ㵻l!|GH.ލc[G:.cHcۀ|-HHƔ4rHGG.Ĕrɷލ{'
+FʜFzto{1ֆæ\vxqF{r𔾈޾ևouiވzt
+"{@zzqӪ>s Ӹ'E{{ְ{@uFqqqm,,z'{rەlQě.[!:cHŽlGG4U4əH|.r@d@@V'zzzzz1Lč{*qxm??wuC+ƛ+444u_1ވ
+
+'*D,w~{{zwgss s͑gvx]qq,ddd_{{_{z,~~vxxM~3,t{k.[[€||c;}G|4D'VE{{dև'Dɾĩ,~3Ɉ;:c_{h{ɷĞ(ě'z~m?'Vճmss sBsssg>v?xM~Ü,z'{__r{__𰇱
+~~?vvv?xM,'*{1쌴«:-=:c˞H¿X=Ž^^y[c䮍LlL֘,qYFz
+"t{@֟rֆ"~~~qY"{JTc;1o{{J.;ˍzx>gqUtw\Őssssss sg?x]~ʜ0'{{i_riD~̖vvv?]x~~qʠFn...ĵQTJ˞Ž[.[[•^yp)!G.ܙ Q~~qqqY@Vtr跾Fz{ĵ||-˙k.H J...Hzʖ>mÊ
+q]ggss sgxx~Mqʠ,z"֮ܮ'Ëvv>>xxMwqFzU-}.˩;.- kk.}|[}H- ^^)ppS!GHƔ赀lļq~~77qq{*{{
+,U:|[«}L.}-TGTG=HHF]vŖ'zq~]?\vg>gssssssg??Mʳ
+UVrrɔ~xv>>vv]xq,Y@.G-Hވ.HH.ˈr.Q$^^yp2RlQG숤޵|l.3qqqqqz@{֮_,qwqt𙞴l!||=Q«=TcH..Fmv>z3~v>ggggssssg>gvmq,'UVލk
+q~?vv>?xMqʜYzU}GHɔę֟˵[Xl|-TRȺ ^^y22RG.}l˒ʳF33qÜ{V֮{֮{FqF{ەl!ll$$Tc.H㈇UzFqѪMFæ\v>v>vggsssssgv~,FDV{@r޾Fq~vg>\v~qʜ,YrK.HG-H{֮r{.$X:$^yy^^^^y)p22)R$[-cXQt'F,qqqqrV{{{ևFqwÜܛ}•X:cH.zz~~z,qѪv\v>vvggsssg>g>ӸʜUtr𾈈ވɮF3M>v>gѭxq,Y@˵|--iVrɮd;H[lQ:Ž ^^^^pp2pX[Q|輠,DDzFq~qr@{u{{{{tqqMqó{1.$X ^^ c.H.{FFqw'qg\vvvvbgssgggvx~{𮒼FqË?vgvі~q,z
+
+cTHˈrև{=$6=T[R^^^^y)R$=T$ɘ3FDzFqwqzU{ֲt*u{{{Et'z,ÂwA־-[^^^^^^^ ;˵.{
+zF~Mz'qm\>vősfggggggvѭqʠYr@ևtFqӖvg>g]~w,FFFF@.-c.V{#𮮮;.c=¥ T•^yyyX[…=•}rqD,qq tu{{{{F]֤.•$X T..{zFqwFD'q>>xsgggg>>>v\]ÜY{Uqxg̖~,qq.H:}Hˈ{ɾcccX$»TT ^^yy)y^[….ֳF'',q~qἲ ֆVV*U'ʸ?#(HT=[«=$^.D'MM'~>>g,ggggg>>vvv?ӂ~qʜY,,~̖m7,- .˛k{舩HQ!Q cۉ6=^yy^^ X=[…qFz'Fqqzu𷾾x\md(.:T:T=[Ž$...U
+Yqàwmgggg?FYggssgg]MÜ,F'DUzF,MggŖq"u.} H{r;ۿȉ$:cl T^y^^^€hqFFqꂜzC#{'"F>mÊH:GT}Jcc :[ .ƾ{U'z,qqYugvӜ
+Fgsssgg>gvxqq,q,q0
+zUtt,wё͐gggggm~z..1_1쌅)pSpȿ cH…Ž^^^[qqqʂ ,uևzz"q̪>> : Hĩ興(;c T[|}ĞH˛UDYC,ő>wY <͐͐͐s gіꋂ~q'DF~?gss͐sggggv?.cHčƵH})S)))yXc}G$==Ž^^^[=QqqÂ7zzzF0~dHH..޷𮁽{ɷcT[Ž| ˩.}ƾD"td~gvmʢssfsssssggvŪ햭z,>ssssgg>gmØE.}HLnnG|Ž^)RRR)py$H}Q«Ž^^^«[|޼qtV{V4U
+z
+ww,*+HH.aɮh33orJ[Ž«:J.H˛{4{v,gssggsgggggggv\\?>,FxvggggvіxH ĩG^ȉXR^$JcG[===[Ž^^…l~?mm7''Fz
+z
+DUjhJH.𰲲Fqꢜ{c [:cH{uVdu
+ő͐sgsggggg햭]M,F,` DDw?\ggg>g̖x}.;Ğ^Ⱥ^|T:R:;cT=[Ž^^[lGxxq'
+Yz"'Drc.ɇ,q]\\3orĞ:=«cJJc}˛{{{{{~sgg77mqCEt
+\̖̖~qFDHc $yԺ5 [ H;.}=Ž^^=$GYx~qqYF,~wqq,"tt{ɔĞHĔֽzqmqz'ur:T=HcH}--}H˛rr{֮rqső ~0,,,33,'tr+*,\~ӋqFDt*{r˵}.HG[)Ⱥ»}(5H TH:T==Ž^^^^«:ӋqzMwq
+*{@nĞ.ޔ4
+qm*u{{.GGcc:-}.ękz,q,<gÜ'*ީ{z\\xwM~Ü,z'Euu{{} }Hc |y)yȿ.&5Hl}-:TTTŽ^^«[-{3Mw,~xxq,d𷷾{YqqFEd{rĞG.;;J }:GG-cH˩ވ1{
+q,DE{{{@ }\\?M~wqq,DtVuC{r˵cHH=X^)Ժ-kQ;. :: :•$^^^[X3zձqӖ]]~q,{{qʠqttt*ttVu{Vɾc-ĩc}T}Hęީޙޡr*V"g~,z*u{d轓z'q\\v\mxwq,z{{Hcc =ypȿ…GGHkkJ-cH H.cJc:=^^…[l.Owt??̖??x~q{𷡍_{~mÊ'DtDzuVH.J;;.c==Q-˙Ʃr{Esg~,,'*@ccė77,7Pŭv\vqÜYzUtEd@ɷHHccH}•p)-|Q-55:l|˩.HcJJ:=^^^«!˒zt,]?xӢ,{ևq̋F'zq3*VrĞ.ĩcT=[H˩.Ĉɰ{ 'ggg̋øʜFzt֮ɔީˈqgvgxvv\wqq,z˵H Hc«^)|.H-G5|$GJ..舔. $^^=!7,'ttzwv>>?DFŪνzz,37qYtVVVɈ..˩ĩT[[´}.ĞH˙{@d
+ggŖӋ]~~qÜFU{ɷɇ~gv?wx]wqMqDt{@cHcH:==^^)y-;--|$ۅ.Jkɔ.cT^^[| ~Dqvv?M3
+0q~m*V''z~'VrL˙ĩH[Q=..ޔuEʪgŖ~Ӌ]~qY{_r0v>v?ӂqÂq,*{HcHc}-^yȿ[ˤɾG:H:J.޾rɔc:=z7??,zvvv?0r𰚊~ꋋ~M?m'*D'ʢqևěވk舙˩JcG=||˵ĩt~gM~xx~ʳ{rܮr"qxv?%w`]ӂwʸ~q,t.HHG|T^yJr{H}-- :|c˙_r{֮rĞH•:L{xʳvvvv?~{37mxы*V
+"tUz,qqrɷީ˞H}:T-:˞H.tzFgx~M~]qʜV{x?xFw~~q~q0cHc:G^c讇o{Ɉ. :«-:.{{{{˞H Ž-coq?q~vv\mq,@{uxvv????m,tDt
+0{ɷrܾn{rkީcJ..r,>Mw,"{{{VUFx?xZ~,FFӦM~~qóDE@.} }:}GG^Tɟ.H:-|-Ĥ{{{rĞc}Gc_qӖvmm??w@q?vg>v???~'"zUtV*"޷k{{kޙ(((.-H.q?qq~wqʜFD*
+q~??ӋzË~~3,**{.c-:Tckd.cc =GƷ_{{r@W잌}|貳qz?']]MqF{'mvv>>>vxі,DDuE˩舤{{{{_rkkk.-H.ꖪvmMq,qzDt"??x~q
+Ëm~ʳ"tE*r.H ::-$Œ4{HHJ. [G}d@#iީ.|Q9tDŵEtFtE"3v>vvvv??і~zU"'VCd{{.nɮ{{{_5cc1Ëv>?qFFFzz4t'FіꋂËxx~V{{.H  }-=$o.Hccc!Q-c-H_rr(JcT=[!!HtudExm,tVV444dDm\g>vvvmqFz"""t{@ɔcc.ę_{uu{?mѪіx~,,'4tt
+FvvӋ~zF3 ?xxMw,tu{c}- :•$ o9rH.J.JGJ˙k_{𔾙.c T=Q:V
+tmq'և{@'g>vxó"''D@𾷷cccHn_{{܍::}xv\\xM,tt4Uݘ,qv>?]ʓqM~MÜީĵH-:T|=$:{H;cc-H֔i{{𾷛Lˈ#{'wm]~'tVrr*'mvggvgvvmq''"t{r1.c -}H}ƈrc::؞m\\x?ӋÜF't*44z~g>>xʓ{
+ʋDƩީ.-:Žku˛ވcT}j{h1ވq]~q"*Uzvvvvv\Ü""t@1( -GH썡r{u{˵-: _x\?ӦӋ~zt4Dzwg>g\>v?]~q{@q]qq
+tɈޙJ} -=[[(ވk( H_33AtU{@@@d{{4A"q~q~q,UUz0~g>v\̦Mq''D{{{{ɷĩ;. G|}č_{}:::{?̭\?Ӌ~3,zt/w]gg>gvvgvӋʊt{d@D~ʘrLީ.c:T«T4{֚:TcA33Ytu{U0O33z,qʠF
+gggvg>gvvŭqʜz"Dtu{Ʃ..c -GG.nr{u.}c 轠?m??]~~~~ҳΟ,xvgg>v>>\?x]~qzzH}HĩJ-=€Tz{5-T ˈt''D,7 34o{rrUz'z,q,'Fʋmggggggg>gv\qFz'_ީ˞J } G-_{{{{Hc:cĔ3?mx?x]~wq~7wztVD\Őgvv>vxxx{{@{Cu.:T-}.˵T=[4"qz:T(',F,~m7qַ1_#{ttDFq,Fqgsgggvgggg>mx~q,'ti跾.-G}}޾ܮ{uuu{ީcccˍֱ]]]]~q,ʢ]wzr@vvg\>g\vv?\xó{{-[Tc;.[«[A*Â.J˾{C*,~ggggggg<
+.HƙVDÂMËmggsfgg>vŖ]qʜF..˩ވޙH}-G˩{{iީɽ]xxMwqFF]Vzx\vvvvxxʊV4tˌQ[[|T-.Hc}[«.ܓ{ڽqqz(.;(u{EMvgggggggg̦ʊVKe.ވ'zFÂMw,qË̑ggggggvŖ]q,D{Ğ}}..˵:T}HJ޷𮇲tt֮ޙޙ{Â~~~qqÜ"zY]w@>v̖v\vvxzA033r.l-}TŽT{Uqz޾tD'F~bgggggggŖYޛޙUzF,wqMꋋÜFzFggggggg>Ŗx~qʜY
+{ޞ|-}HH:|-HitrֽFqqqwqq,q,F?F vіvvgvvx{VF
+4־.=|T:|[$.3z 37'{޷{,qmbsgggM, Kև֮k{,qʂMqDt*Őgggg~q,,FY}G=[=.cH}:|T|T-Hotz{_kɇ'zF,,qq,,zUE"w]ӳK\v?v>vvmFt{{{ֈcQ$|T|T:{3uwz,őͯs͐gggV{@V{r𮮇VU"qӋqt
+gggggŖw,FFz{H$GHH}G|G}ơz{{{{{_֟'z
+zFFF,F'x] ]?gg>g\?qƛKd[$=ەXTcqd<ݽ{ɮ̪sssgg,{"4{zFÂ]~zud<ggggggvM,F0
+}T=$X!G} }}Q[QGHzzDo{{VEttD'
+zY]~@v?gg>gvvDe@əTX$ll$X:J4qd@<~z·rrrֲg>s ͑͑gggձuV
+"EDFqwxzu@Cggq,,Fz4}:[$ R!G}}}:T[=G_o{_{*V*'Y*M]z@?gŪg\gvŭ~.H-QQЍ/N=X l ^ ɼq*d7<qrrևF\gssBss͑gg'ΒDFzut'z,qM ,z*dqőgggb̋qʜ,0
+.:T•X 6-}|«tz,Vr___rr@{{{ztDzgggbbmÊc!! ֽu;^^^^y^^=J{A0u7zVU''gsgg>vgUD,ʜ,Y
+zFqqqq,_{gg>>>?Ӹqqʠ
+ɩ- =^ } } …:'ʜzU{_i#dzYzqqu𲂑gbbg̦r쌻l[J(_5=^yyy^y^^X.˾Vu{zsssgggg>>v3zUDFq,,UtDzz,w,oomvvb\x]~qq3D}}Hcc ^T}-|-3{@֮rɷ1nnޡ𮇆'dUggbgg̖,{컅lG씇h(X)y=}ruuD{,q0g g>̦ó"UF,,3,zt'zF,ʜttt~gvv?x]~q
+kޞH}HJ; =•X}}}GTHz3
+{1@{֮11ƛanU
+zmsbbgbgz{ޞŽlXQu/()yy^.nAuzqq m,~gssŖ,'"Fw,,qqFt'z,,tt>vvѭ]q.H˩˩c[ }}c}-HĩK{{rk...HH}}}H.Ĉ
+t~Őggggvó{Ž•lXHQl=:c.400uE,3VFm̖~~gfs~D,~qFq,zt{{{t՜~~'qFFxѪm~q
+{@..;;:|[HH}}-Gc.ܽL @{_1JHc ----֟"7gggbg?~ʘDH€[XXĮ/}Q=:;˙_V"F3~ss%,''D
+wq~wF,,{{tq]ҳzq,`~xqީ..J.c}:T|Hc˞Hc}-:}讟o➛dE*ܾ֮1.Jc-.ľrU,mggggggv>>q˝Q|XGrd"DFtD,q~g>v~gg̋'''zFqË~,zzz'{{{{{tzæx]]vvv̋F'F,qd˩˞..H}c cHĩĞH}-Tr_-L*UUrk.c:-G}ˈɇE'gŐgŐg?w
+HGGQ$$|H֟rɔrtqvggxw͐gwÂ~ʜDD{{{{,gggv\\> DtD'tu{dޙވ;..˩ޙĞ-|kL؍,,Yr𾾍ޛ.c}}HHޔ{{,gg̖x~q,zz}G-T:}}:X$Hև{ztq7'*,tFÂg>g>g~Fggggv?x?m?mm?~qtEt{{"zqmgg>\v\v>g'*{ɔވޙީęĞH}J}-췤.âFr((;....{Eg,,FH-G-cH}$և0qq0zV
+q0t,Fzqm\gg>x,~vg>g>g\g\\q0zuu{{zʂ̪vvv\v\v\gggFzDEEu֮rrkk興跔ɔ_˙.H}G蛞~
+{{ɔkĩľɇ'qg>gzUzzzF,{-}cc.....,'0~q*q'tt"q~x?>>?,~?ŪŪmq0{d@{{{{@{Vqꋦ?\?\\ŪY{{{{r𮮮{rH}G}<gыʊDV{r{{֮rk{tUggŪUUD'z,t{HH..ę.=-{3mӂmgm~z~7qFz't'q~7x]mv>ŖFD'ճ,qʳz{d@{{{{{ɮqq,q]]m7~3FzU___և{{䇇rr.-Ʒ P>zUVVoUz>gvʼV{.H˩;1JGTV?x??bggggwzDFmó'Dz]xx?̪v?~Dt*uu{{{{𮮮֮@F,qDtttD,~qqYYD'{r{{܈c{PvÜFDtto{{zFq?gzVt.ĩęě5ČQ-"Ë?>>ŖF,̦3z,qMxxx]v?Fdɮ{{{r{t,'tEutzF'DE"zz{{r_ɮr{{{{{{{rɈĞH˾Ɇ7gb>ʳzD''"zzjtEUzF~?ыęޙލܾG?>>>̋Mʜqg,0q~w~~~x]";޷#r@{{֮@{Ytr@{{*ttE{@uD'zz{rrrɤ˩{'<vg?qYzzz
+zqz{{zzFq~F{@r@dě辙1i--臇U?v>>v~,w\gÎ,zFꋂ~qwq~~MM~]]7àɾ...ě#r{{{{@rrFzDV{@@duC@+.tzt*uɔƛg>g~,,FF,qwqqqrɔ𮇽Y -HC>?MMx?<ggʳF,~~ʊzFz,qqqqq~qqtHJ޾{{{@{@{{{{'zztH}쩈܇_r_{ީ.LHƈ_޷{'ŐgggŖ`w~qqqU{ɔ{" #__ @{{{.{qv>?xgIF,q~qq,'zF,qʜʜʜY{nc˩ޤ𮮮{i𮇒{ dFztu{ޛ.} }왾{{ց𔡈.؝-Q-޾ɔ>>ggŖ~~~q'@r{ɮrɮ_{{r{{rh@d*<vxx?xx?ŋ,M~,z
+'DtDDzFFzz'zD{r_.c.ě@r@r{Dtz˞Hc}}{𮇽֔ީH:«QlQľkķ>ggsgg???qt{d{r{{{{{{𷍛Vqіxggm,xq,F'tt'zzt_i.JHH1ri{U@tzzzz't{...H}c舷{{{4=$l6lT޾Vg>gggggb̖V{𔾷ލ{{𔾈޷ևVn1֓4@{gxvgIgŋq,ӭ?MwʜFzD*EUV˵H.ě𔔷zD{..H} }}H.ޔ_{t''4֔ˌT[^^XQ 5.vgg>gggggvvqʘu{@rɾ1ޛ{{𷍈ɮ֒*U4r4UE,v?b>ggg~]xӂM~qFEE*Vu{kk(J}-ލ{3"tttt{𔷾.} H줮{'F"rcT=$^RyRX:VvvggggggvgvŖqF{rč{{֮𔷾ևttt""/֔ĵ}{*,іx>ggsIŖM?xxM~x]q,zDt{{V{kĞ--H.ęވƔ3Eq{rnH}}Hޮ_,,FFFJ Ž^^^^ l=}5(.ƽvgggg>gv],zDtE{ޛ{{rrV4U4.شć{,v>gőgw]]]~Mm?qFzdd{Vu{{n興. G-}H..H33z{{k˞.c}:}Y{uotz,,FUV; =•^$[Tc(HVgx̐sg>>gvŦ~'4{r{{{"""'
+zYzɾ.}GQɮrzDzvvbggss>~qw~xxxxѪm~qF{և{{{{{{(HG-c}HɆ33uqr{1˞c-}H_ʱ{tDF,,F:•^-J޲vx~mgggg>>gі~""
+U4֮{zzYzzrH|Q3FvvvvggssIm]]m?tV{r@rr{{{u˞-GG-T@43Fu{{{{1˵H}.췮tqqu{tDFFČ:•G ˍVgx~ggg>gvmq,Y0YU{{{F0,,FFFzzr.}G-.跈qFwv>gssŖwxxxx̖mq,z{𮮮C{u{..c}:|=«[«•"A@{3Vd𮮮{r{r𤍈.H}H}H˙~{ttFzu{ޞ TJ(ީƾqŋY~ggg>ggvv~333,z"zzY,3q3qqʜ,"t{r𾈩.|-˛ķ~qxvvb>ggg~wx]]]xxqʜ
+{@{{}-}G$Rt{ɮ˞Hcc.qwᓆ{{D"z"tީ.c޾ވы,Őgg>g̦â3,Ut'zFz''qqq~~~~qqtcH.qMvvvvg>g̋~xӋӋqʜu{{dt-GT[RȎAU3Uik.H.˩ޤoz,q{{rkީ.r޷qxzYÖg>gg>vÜ,t,7qFq~]~q,{Ğ.-Hr~]xvv>ggmwqx]]~wqʜ,F'ɮ{z[X^);UnuD֮kę܇'zz{{{{_𤈙ę_.L˷3M,>g>mó
+zzzz~qʋm\]x\\ŭ~{{;cGGHH'qx?vvv~q~]x~Mq,qqzqq3q{ŽXyc&"4VrLnz
+֔1ޙ辷krցցotDoܔĩ......-H"qx
+DF~vvgg햦0z'D'qqzzmg\gvі\gvvvdĩ;.cGHHDqx????wxMq,FF,q3q3zq7mm"4-=»(&4
+L㍏"jě跔ikև44hut{1荈1ޙJ}}HczqDz]?\>\v̖F,Y'sv?>vőgg
+ީ...--.d̪???]?qqq~]xxMʳzFY,0M~MM~M~~~wMx̖qFHG[=}U4H .;Ĉ(ɮ{E'0,FDu44ɷĩJJ|||Žrzwᘱq]\vmʓt'q0'Uőgv>vvgs~#ɮH... Hړ??xxqqqӦxxx~zY,3~xxx???v>>vqzU.}--ֈ.T .ču.r{zʋq,zt{#Jccc -|ێ!•l_qqqz''zwmzEDzFFq,
+tV g>>ggggg~r.}--.JH;Eq>?~~MqqMx~q,,,~?vvŬg>gv~~~{ީ.ķ4:|THĈ{1˵{̦~qF't{4U{@˞H}TG=[llLDqÜtwM],"F0q@{z<>>g>gggsqUɮ{GQ-c..cH.dFvxx~wqqqq~xxMʜ,~>\>gIgvvv?~,Fʂ
+4ܔ"{Q=T}Hޛ{{H.ּ3gqFz{ևɷ.Xll[q~qqqD'zqq,'
+q,*VgIggggsgÆ{{c[«GH;. } vvx~~~qqqqøx]ÂŪgggggggggv~Dqq
+{ɩ-«:c.čnľ{Ŗqz'{{k6R=}Įq~~~wqʜzFFU,0qq0gg>ggs͑svgqUև |[-.c HDq̬?~,,qqqq~Ӧxx~q~vg>g>ggIggg>ѦF'D*t,ʠ܍.[[HH..č{Ɉ} 쾮7̂,z't{{Ry)«{ʂ~qqqF''zzUF,,Y
+ɍgggg͐sgŬ,{{Vƌ[X[}Jc}c\g?~q0F,qqqxx~~Ӗ?ggggsgg~,F'''*V'ʜ,zzd|cHH.k{ܩ.gq'{{1_n˻[ ^pppp)y…-{,qq,zzzD'E{qgggggsgmF֒ƨX$|Tc.cg>m~,FFFqqq~~xxM?vg>gssggggmqFFFFzD{Et',,zd.Ž«:c.k}-Hu\̋,''t{ěލr܍:X)p
+U{[^=-HJ.Hkə}.rtMvŦó,z{{r..˞H.k:^p
+ݘu֮tt*U{{7gg>ggvqtַ.T[[:}cc}-އꖭÜ
+''zFqÂ~~~Â>ggsgg̋qqqF@u*ƌ^[c.akĨ|.D\̋ʜF,qUt{{rĞHcH c.(HT$^愄222pp^J{zqq,,YzztuhVUzF{'ggŖgsgxzr==HH.HGˮqʳ"Dzz,q~]~qxggggsssgg̖ʜM~qF{@Utލޛޙ|˒?,wqÜztu{{r(c--;c:[Žyppp)y˔qq,3,z
+z{ɽVYq3zgggőgv̦Ӝݼ4LTTTT:}Hc..THK4,qwʳDD'z,q,Ëggggssg?3qxӢ,@{{GTĈ#[4ʢx~~qq~qqrɔc-Tc.cG=^)yJq,,
+"𷾮9@q~zʖ>x~gggg̖w,'UU@ػ:T -}HH...:ˇq,t'~qFgssssgs>?qqʂ?m?~qD{ɮVĵG$˛{ɷ褙ۅAӋwwM~ʜr-|: }GT^)yyyy JFqqFzYz''
+t֚{D0q73DxggіӋMw'U4 cJ.H.H˞. -Hqqq,zUFŬ̖q,,?ggggsggxw?m,{ɮ@{.-»-Ĥ{1|TɠMqÂwqq{rɷH-T-T¿))Ժ^^yy^ɽUFz'"d܇ht{@{q"vvg\q̖~wF'zַ.ވ.:Âq,ztt~Ő>̖qqM%͑vxʜ,Mxx]Ü{r˝=…c;_@€cOqMwwqMqqq,L}-GGGT))^y^yyp^X*z'D
+"u֟9{{"q'\gыqmM݊
+{舾ީ޷kcİ30D~gIm~ősggMFø~]~q,t{Nr@H[X=ck֟4ۅO~qwq,z{d1˞}:-•)SpԺyyypp֒zz'D*d{4U~3U
+v>v?w,ʳzz𷛔{{U,Ӌx]qz"UU0ggsgbZ?>ggggv%xqʳzqqq{rrr_; XuD"
+u{_.| Mwq,qFYU{r .HH cT$y2pyppppXֆzz'DuUt{{33q벲4>>>v,3YFz
+z
+V@#r_r_֮ƙxӂqqYY
+Y~gsgbgm̪Ū>g>g>g~q,zzFÜ{__kJT$z"V{{uGL7~q,,V@𾷾5ީL.c T[^p2ppppp2ppytFt"z'4"U{r{
+0u{Uv?,FFzzzD{W"nɲ
+mqY0,~̐ggvgg>g>>Ŗx~,zzzi_;H[ rtʠu܍J~M~q,YzUr𷷾5n. =¿ p22p2p222p)y$ćquV'z'tU{u{V'~v>xà''zYz佟֮@3{,̖óUY,~ősbgg>gggvgg>іMÜFzD{:=;4zqq'4t{..M~~~w,,zD{@knH:=$X^p2222)ćqtdFF'"U{{Ur@ʋv\qFFFEVVhrK
+3_EUqʠɒU' sfgggg>bgggv̖ʳ'tt{1Ğc: Jq,zDUľrwwMq,,Ut{{{k|=[Xyp22222^֓qʚd,,FYU{𮽼#@zq?\,FzF*{+{*Fƛ*ggf>g>g>gvv~w'Dtt*u{nĞJ: rqz֒tzq]MqF'{{{ش|=$^y2222pT֊qq,,q,"{rmŪm~Fztt {VtUzz燮ƛ.adtD*gb>̦qzDt{𔷾(荛nL.H :"z'*d{{DwMMӸq,,t{{{֔˵ :G=Ž^^pp[zqEDÂ,qâU{{qŪ?,Ft*"@EDYAڷe+D'EUq<gbbgg~Fu{{c:Tc@z'{u*4U"U'wM]wqq,Fz{ɈHL..Jcc}:•^ypp[H֊곰{q~~~w~~qq,
+k蛈rɍH\ʠ'Dz'*U
+zFz'rrq,Ūgg̖qtu{d{{𔾈L˵ :-숰*t'ut'"F0w~~~qFzz"{'Yrވ.H:^^^yy[H{7FdtV,7ꋋ~~qqYޛě{0]qFtutz{Y0,YFzzVɷkrֽq]'E~̖~tuK@{{{ީLH-TT}ˤtCz3᜜,q~ꋋxꋂq,z'{qq"4{辡ވHTŽ^[֜7zt*
+~m??xxMw{ęěrևrH.ֆq~~,zYDu"F,Ü,,{rĔtqxʱC, àY1ލri..:TG}_*𽆒dzMx̖,z''U{d~U{{@. ^qdDqvv\wYnƩޛ#r{.H.{z,q,{{ztq~0Fz'{{.Ĕz\ŦFd*,,,,,u𷡍ƈ˞.-TTHDzEKuq~ꦦ\vggg>̖ʜ'Dt0{t"c[H~tVggg>x"{ĩľ{{}J{'""{{D'q~~0F
+t{{Lˈ{zw]̂"@V{naޛ.HH::T-oz'ƈtg>ggb>v~qFU{0@V'F,ʜ,'cŽX[HEgg>g>\ŭM0{ĩˈ{i u*t𾍷ֆztz~ʠF'"{𤍙ˈx\gU@dCCC{𷍍nޛޛޛީĩ..H }::-ްzg>gggg>>>vÜ,'t{tFF3~~1˵[H~34~gggbg>v>>>?M{ĩWc ˍd޷A
+q ~~0z"t{iw\7FV@舤kޛޛޙĩ...Hc }_H/W>ss>>>xMw3ztttt{{vV07̖x]3˵ŽX㟂ugŐg>>>>\M{˞.ƾ_;.c Ѝ@@޾Yu?m]~0"'{1x\\sʆC@kɗrrɾޛޛĩ..cc c _HW/I>̐gss͑g>>?ʜFz"tt{t?v
+
+̪>?~q{}•!Ƽ {AŪgsgbgw".ĈrJc H޷k(ɇ,qq3{ɾޙ޾ɮrFx>>\F{{{Vu{{;JJHcHc}HHL4؍DB s g,3*,mqD'ő̖qqĵ$X!rggsggAV{#J޾rޛ(֒,~q3,'V{𔷈ީěir{tFx\v>>q't_r@{V{@ޛ;..c.cH.؍EŐ ss ss>dEqt*<ggx à'Ž ^€-34
+gggsggg"r ĩęƛވވ{̦~q,*ˈ_{F??vѬ\q{E*tt{ɾL˞.HcHHHHHLñ~s sB ss sP Psgg\Ü֮{U,tEgggg~UGŽ^^^^^qڍVxgggsgĝ,Vޛĩ5r{r{d𷾷rFʳFz"{{.L.1r{Fx?\vŦz'ݘzFzr..JHcH H1ޝ곋gsBBB s sggv~"֔ޛ𮽽V"ÜtEtPgʼu-|^Ryy^T޽duv>gggg~,'ލ޾krqqttt9{dxvw,Fz'tV.HH{]??\>햸w,,FF᜜r....HcH }HH.-qgg ssBBs s Psgg\,.H}Hޔև
+tVYggv>>ÓƝ^yyy}4?>ggs̋'E{k_rq]qqqqqz{{
+zdӪv?q'E{˞Hˍkr{zqM?\g?~Mwwqzַ.HJ.JHHHHcH}H }HHLH-mgss 8 s >vqVr.c-GGG-LɇVDtgg>>gvØV|yyyHrFtttxv>>gb͑~q
+{{{{hzqqqqzqqwև{?vw*{@𔷈{'wxx\v\?m]~Mwqqzr.HccHcHH} }  HHƤ}mmgssB s gg>vmw.H- G.VVU*Egvgvv~"•^yppy r,z'Fm?vgggggm~qDFz
+qqҜz{ɮ{{,]\?FE{ĩ𮇽t'ӂ]~]mm???̖~Mwwwɔ˞...cHccHcHcHc c.ވTGmgssBBs gg]t.JHc.HHHˈVt,gvvq'V}Ž^yy)=rqq,qvősg̦ÜzDrr{ttkވևqmx~qF'*{Ʃލ_{zʂӋMqqqqw~~q.J.JcHHH}cHHLcG<gs ssggv]ƈޛi{VVV{{tm\q"H¿^^y[3óqvgg͑͑g>g̋3,zr𷾍{4uH:-HƛrD]Ü,z"{r𷈛ět,q~ӂq,FF00~~qàĩ..cHJcH}H}HHcHJ.:ƒmg gŭu_{{{{{{{{V,wMqz@ Ž^^HޛuFqFqʂvsss͐sgvmʜFD{ěrr:=HĈ{qqqqY't𔷈nniɮ{Uz,q~qztVV"q~qz{𷷈...HHHHcH.c.JĞ.=֜mggssgҘurև{{{@@@{{@{tz{}=ndqqxvvssfgŖʜF'{ɾ:Q=-HHޛ({z,ʜ{i{'qqFzEu@@{Yʓ{ޙ.HH..J.H}=|H]gggg~d/{䒆{@ɮև{@u{𔍩.c}GkHCʜæbgsͯBBssgv~q,Fz
+z{{kL.H--= ˙iޙ{zzU{1և"0qz{~,{{...G«؈q?gggbgvggmu4#޷r@rև#ޙ..Ƈhtwq?vggs sg̖x,ʜ0D{kƩJ ::-T|T}J{{..웍d{t{𔷾k𮮇,FU~D{{{r蛩ęĩH=T}{zÂxŐgŪuuHHޡr{@#@ޙޙ褤__j mbs s Ŗqqq0z{{rkL.c} TG._t9{H}㞛{Ut{{kk{
+z,ÜzV4rĩĩީ.~%\?m3
+V"H--޾ɇV{@W{rrrɾ˞˩kևjk؛Ūgvőg s Z~~,*E{.c :G;(&zzz5GL{t1rU'D9h_qqzFE
+3Yrĩ˩(ީ[«T-؍uz~~~~M,VtF GG-H˙և##rr𔈛.H..k4j/rd,Ŭg>g햦gsg̖xqqttF''{˞c޾{{HT:H{{rkk{{t*{FqFz 30
+{웩ީ…-ľ,ttDqH;r#ވ舡ީJc.ězz4*vvmőgg?~q,zzø~w,z.::J숡{{iޞ =-Hč{rkk{VUt{z'zwmÜ{Ɉ˞HŽ[--}ˈr"ʜFz**,U{H}G|==.ɮޙ荾iiiLJcHcutzzz֤m\>>ӂvgsggb?x?óz҂m̦~qĞ.:TH.ޛ{{ĵ[|-HķuV{_ii{Ut*{{{tDzFwxgŖqɔ잞Ž} ."FFqq.HT|:ޙ跾i1ީ.c.ķt܈ʪv\~őgg??ʜFqgIggm3ީcc..ěrܾJ[-ˍ{{i{Vt{{{ut
+z̐ggggggɍ..H-|HH}'zzFqÜ.|y čĩę荈c.ġ𰽆ttɈL~̋x>wqvggggvm?~,~ggssg̖70𾈛ވk!t_i{{u*֮{DzzzF̐͐gggvʓrH}}Ž=....ƈV
+DqH¿^pp)1;˩ޙ興˞HH˙{V{izŦqxMq~̪gggvv>vʜ,IsIssg<ꂠ_ineވ˵ QHķuVt{i{{DqŐsggĝY.}H-[|-ƛ {'zzʂ~3' c yRpy޷;.ę蛙.Hc{{{3~q,vgggvvv>v,őgssssgggg̖,tuu{...ĩc•}Ĥ{ܷ跾{ttUtEr{z,~gs͑sgggFH-T=THĈޛ{*FFFFʂ~,{ =^yR.n.cHJޙ.H.HH1rև{{rdqmtw,\gbggvvv>v~w~gsfssggggqUtn...˞ƾ荍{tUDɮ{3ssssfgŋ3rHH-}. zʠq,qq~"{( [^yy^}rJHcHީވޙJ..rև{r{E,,q,qvvvvvvv>햂~gőssgggggŖMtttt{..;H•!}Ĥ{־ĩލrVD{rk{ss͑gbvggg.HHH: .Ĕɮ{C,q~Ë?~Dތ[^^R^$_{ܷJ:Ĉ....ޡrr{r{Vqqdz,q\>gg>vvvv>v]~Ӗőgsssggggvŭ~tt{.l¹GޔɈ.޾Vzt{rn_{{~bg>g7q˞.HJcc;r@'qMꋂ~"r( ޷{rJHވnnޤr{rɮr{*Fd"]x̪gg>vvvv?~gssgggggvgvʳ'Ut{ɷĩ˞-|[˾rrr.H.'FFzz't{#._q,~gs>gg>gqF.޾{{{UY*~x̭,zV־$[cľ{o{k.ވ1n޾_rt3tdt0]vvvv?~xőgsssgggggv],tDޙ(H|˩ɔ. }.֒"0q,Ft{ވH}.q,E
+ b>őgɷޙr3*qMm?vqFTŽ…{ěiܮ֮ɾޛKDq~{"Yvvx3̪gssgggggg>v~qFU{𔾈舩˵GG.Ĉ}HLuqwq3,{-}q~utË??\̪̋3
+{{{FU,qvvvv>xÜ'TTJޔ{tɈ޷{{{ɾƛ{q~7qƍ{U'zq~vqFzFҋőgggggvmʳ"tV{r𾾾ƞHH}c辈H.{3x7~q,'t{.G}䆊qm~ղ*t'Y,,qÂxm7
+U37,]\vvgі]ʳɈ쵞ľr4tč{{𾍙ƛt~~q{V",q??zUggg>>gvg{@𔔷.H..ޙ1zm\?xqYz{HH.}koqm~tz~~'ݘD~3,'zF,'Etʦzw]Ѭvg>v>vx,z1܇"D'D{{u{iލtqqq
+tƔU"D'F,wx\qt󂪐sgggŬbggg?zD{{@k1L˩(辤kɔnij7\\\]q0z't*H.H}jMzʦŖM,E*D'qq0zFC~ӭ>g>v>vv~qz4䇒4j
+{tt{1t{_iUVtU,v0g>vgggvvvvvvv\Ӝz_ɮ(r𷷍dDѪ>m~qT ~ձggg̖qzt{r{{zzFqvggvg\,FD
+FzztE{Vqzo{@ڷd~'{{_ **Ew#"g>g>v>vvvvvvvodirɮ{{{{{_uzqv̖wt{{.}G|}rU~Fzqgbgggqzk1{tqx\gvggv>gvxq,Fzzz{Uʋ̖ʓ{{{'qM]]0YE{{_@{{{{EDF,q0VŐv~ vvvvvv>vvvmótɮr𔷈rr*{{{zq7ggŖÜudީ˞Hc=«QG|HqÂg>ggg>\ƛ{,vg\>?qʜʠ,qqz"tVE Őgŋz't,3~m\?wzuuoo{ee+{DFF@F\M~,~??vvvv?{蛍r{VV{{3mgŖMzH-GQŽŽ|GޮֲDF~x\>gg>v>\7q{dVd{{\gggvgv\]~~qqʜzEgggvF7mg\̖]ʳ'U*to.H--H쩔Fz~F'
+FMӦ?v\v~ޙ{{U4VVV"7gggіFu{ީHcT=|.{*gvvvvvvvŬv\m,{𷍍ƛrֽ{{{*z?>>>\?~~qʜF'*
+~ggMgIfggg̭w,z't'zF0_.QQ|kq{V'Uw?\vØƍ{{r{U4UU<<g<gg̋~F';H:=Ž€}ˤɮ{,vvv???̭\mUƈ@{_{{{z~\gvgvvv?~ ~qq,zDsgggvŬggggg?wDUF,~~HTQ•ruqq'tD'F,wxѪ̂
+ɍ޷{֮{t"""D'F <Psggі~,oɤ;c==|G}ˤ𮮰gv??Z~Mqw~xx~3Y.L{r{*zxg>>\mx,'DgfssggggggŐggŖFzzzËq{_ĵ-Gq
+rr0z'"zFFM?xɇV{r{u"
+
+'~<ggg̖M,F'rɤ(;Jc =|G}Ĥɮ{\]ӋMFճ,qM~~3"Hu{{*]gvgvg\v]~~ʜzDzgsfsgg?wqᳳF,0qq곱ˌ:lGrq'zFq,,',q?*ɮVtz
+'FÖgsgggvіx~~~qz{ީcc-._{t0m0,YF
+z"UD'z,q30Ai.ˍ{{{zxggg>>v\x]]~ʜ,zU
+mgssssͯssbg>?MqqqqYʂqz.UtqUzqqq,zzMӖѪq{r{rut
+"qs͑gggіx~3{cc:T-ޤ{t0''Ut'F
+"4{a{և0]gvv\ѭ]]~,z'',~ggsssssgbbvxM~w~qq
+,qw~]Üu.c •lGHUU~]xMq,zq~]m~rևrz"ʋgggsssb>vgv\іqʜzzt{{.숷{Â{{uE"4{ލ{"m>>vv\??m?x~~ʜggsBs ssb??xx~q,Y
+zF,~,Ɉcc۫W4".{Â\̭F'Ëxvmʼur{Y~ggssbg>vvvmq01ީ..辡ɮ{q"ur{rrd{VV֮ևFxvv\v\v\m?FzYʋggsss͑gb?xx?m~q0zzwz.H::Ur5U#"v\và'zq]\uuև{𮽚ʂŐsssb>ggv\>vvі]q,'D{𔍈ĩɮtF{{{{r{rɮ{{z̖іv\v\>\?~qqqF0gssggѭ?qFz''~w0.c-kEr#"7x\vvmq
+'w~]?xqt{{{Vtzʋggss͑sg>g>>>v\іx~q,z{riޙޙވ_{0u{{r𔷾{{rru{DM?\\vvg\ѭ~wqʜF,~b͑ggѭ??q,U4DwwF.HH}.4-k@a
+?vv\>Dz~M]xq{'3ggs b>gvvv\\?xxxMM,,F'tV{rɔޙ{Fzuuu{{_ĩěޛ{ևr@u~\vv?]~zz"Mgggggvvvv??FDD4tDճqV֔aaJ;krGa.W֓\>vàt'Fww]q{d'gggsggŬgv̭xӭ?]xxMw,''U֮𔔾ktuo{_i1Ʃ.č_UCDwM?v\v]ձDtD?ggg>vv?x?x~,F'4"3~q
+*1H.3q\v\vꜘqqʂM]ӂz{ևƍ֟'ʖgggsgŐvmqqꋸ~Mq,Dt*u{{rr{FF{{rޙL.HHJH޷tU֔{ևm>\\3rr֒UDDDgg>>vv??\?]xw/4V7"#rɮ. .vzuozqwMM~qzU@{{ƛ֟Dggg͑ggv?~wqFFʂ]q,0F't*rr{{*'*{֮ީ..
+t9֮ɾWވ{Uq?Ѫx]ޔY'DtDq gv?m??]~qFUtVUzqꖦ~q
+tttz--}G-H3~?Ѧ~3d{tzFqq"{𮽽1rggggsőg~'tʂӦ??]~qqF{ɮqFzt{{𔷾nީęވutzoɔޛYʓLHHrU3~βq̪?xm?]wqz'V{{Fqzo|-Tau{z,] qzDz'z'#ɗ*gggg͐bgggFDd?\Ѧ~~qᜳU4֮rr{'qʳt{֮kkdt"zzz񼚽{֮ލ{tU't{.mʳDED,qxx?q*{d{tqꦦ]wqƝQ-.Fq~{tt{q*zŐgggggggы
+t@{,xmvv?w,Y
+4V{qq,FF'{r_rrr_ɮutttz{ޛKK@ɾɚI>\,*tFqqqq~~,UtE{dd{FqÂqҳu|=Tar{EFqq,Vr{7_ɮEgggggӜ* {V]\vvv?m{և
+qqq,qqqt{{{և䇇tEE{ޛƛƍrrɮFv>vʘ*E*tFqM]~wzUt{{zd|=Tc𒓼1޾{
+,FLɮruևmq~gvMt{@𮇆'3vvvvv\і7{qw'V"DC{du{ވƍkr{ívvgŦzu'ʂqFo{_{״|T|Tě#DzFzH.֟<qt*gggݚ*{@@ {Ѭvvv\\>3r{qqw~m꜓*V,'*{duoo{h熆{{֮ɔɮz]vvg>,*u{9*tq,'ttriĩƩ.-GG|Gˤqn޾ܾ.HH.ƷևVqquz~>і]ʳr{{zwvvvmm?m?{@{U~q]qFDtt*t"z,,0,q~ʳF'{{{_uhjrĩĈ?vŪg\qu{_{{u*YzV{n.L..HH  -:G:GGˤY3iĈ@d{_˛ɮևq{DF?ur@r{]\іx~~~~'@{Uqqq,w?Ŧó'Dz
+zY
+03qq]0E__id_և.ƈzwӭvgŪFtu{{{{z
+
+zUttrɷH}:TT .웷qzވW#orޛrr{{z{~]?x,zuɮr{zq??\xqYzzztu{dt,q~qFw?\FzFF,qq,,qÂ~~v>~'d_k1ɮ{{ɷHHqx\zu{{u't4Vr;.c ::: HJ˩޾_,
+t{nޛr4ɔrrrְVqӋxq,zDurrrr{
+w??x]'t*Vt*d{"q~q,zvF,qq~q3,q~~ꋭŬg>~Ft{𷈍LLƾi1˞Hʸ]m\ʳoEU{ɾ.JHcޙ_{tJJ;č_{{rd{r{*~mӋ~wʳt{{,æ??z{uVuuz,qqqFFí?~,,qM~q~]MM]?x>>vvvŐŦʓViĩĩ;}G!l!Hk舩H,qx̭ótDUVtީ('dJJJJĩևu{ɰuV̭ӂ"to{{{Y?M@uuuqqqÜMw,~]?~???>vg>>Ŗ~{ɍĵ}}!l!-˙ޙ.ˈ{z~~]ѦqF"z{z'U{𔷾11i_{zV.JccHJ;n{VVh{{{0̪v],o{{{oqæxqK{twq~qqq,z'FqӋ~Fʂxm?mxӋ]?]?xx??vvvvі~{܈==[}ˈ舙(("~~Mx?x~q,,0"{rr{zz{_{ևjztdJJc c.˩ĩ{t_ɔ{O>g?,zuo{{Fq~xq' {M]qqÂʜ'ËqF,w?~??x?x?vm~ČGQ«=[[=J达ޙ(k{'ww~ѭ~qqVr@ɮ \ No newline at end of file