diff options
Diffstat (limited to 'packages/ptc/examples')
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 Binary files differnew file mode 100644 index 0000000000..3ae321df8b --- /dev/null +++ b/packages/ptc/examples/image.tga 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 Binary files differnew file mode 100644 index 0000000000..3ef71a7858 --- /dev/null +++ b/packages/ptc/examples/mojo.raw 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 Binary files differnew file mode 100644 index 0000000000..f0441d2bd8 --- /dev/null +++ b/packages/ptc/examples/stretch.tga 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:
}HG: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{Ɉވ{;TT}
-3zu + +F~~ʓɍ{U~x~01gv̋tD'{{+ޛzzUVuuU"zzi쵝-˷{ +
==[=T.(ֆ7ʱCEg>bvbvgvv>?]Ü{kr{{{JG!!«cT㷆ddUVVE*D',~0֮DӖxƩ{F>>vv̖~F4aޔqgt{C{ttt" +zY_˨T=˷{;TTTTTJ{q*æ\gvvvvvvxӂózrr{{{{ɍlGc-.{ڲ +u{{{r@@ ɮY3qqtV'q'r1E>v?qUVtt{{ޛĈu<u{{{utUtDYYziQķ{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?xqztuKV4D,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{zq7xww<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]7wMg>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{tqqFHTco{{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ˌ[HqqD +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̋qqr5cl|ޒ*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,qv>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,zUtECKr{r.H}
}:«
..vgvq,zFq~ꖪ>g>іqqMꖭіxwFzz +zYe..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:
JCFgsgŖ,YY'zzz{쵌=H{ƈ.HJc:|«G˛{>]~FFFssssgbb,Ӗv?~qqvvggg̖Ââmgg>v,~]gggg~DtVr;.JH-GG|-Jrt\DŐsgM'zzzzDu_ɡc}:T|[QJr{ޮu{...HHc[
ÂŪg>g~FzFF̑sͯsb]zvv~mvvggggggŪ<<<>>?,wqMgggg>?q{rީH.c}
TT=(r{{d"qssgg̖qzzUhc}˙蔗{˞.c:|$
QH.mggv,z +FssBs͑̂F,M>g̖ggggggg>Iggg>g\>>v>0qMggg̋zU֔.ccHcHG|TT[Gr{m,sgsggggv<77qq0q3q377qok}=Jiɽ˷֒u{;;.c}
.{zꖪggvgz'zFssssBBB͑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őgssss͐gg>gvv>v>>>>gvʠq~?gőggz""r˵T..G|=|TGcľɇ{@dgDts͐gggv]]]]]mŪvgvÜo1ĵ[ęև.u{JJcH}|«L.ƷËvgg +,ssssBssg>ggggggPsss͑͑gggggvvv>>v?~,,3?]vggg~q +'H-T|.=TTTH֟V7qss͑͑sgggg>>vv??v>v>g>>>>?ػ|.{.ƍ{{{JHcHc}-! ^».ě~gggq"zgsssPsssggggggssBBsbgv]xxv>Ü0q??>gggq0"˵-|=-1˵=TT=ľևFqŐsssgggv>>>>vvvvvvv>vFC+Qę{.ˍ{{ɷ(HcH}}:y=}˙,ʦggg\z'zwŐsPsbgssBBBBBb?MMx?\>vx~FFæ?mgggg~qF"zU.|c
::-}ևrdEvt0ssgggggggv>>g>>v>>>xqztu.=«c1_Ĕr..HH
:::[$X^^y^»1_z,mvv>vgx, +YʖPPssssssssg͑ssBssggggv?qʜFqqqq?v>vg,F +|
;@rcG-
J-.r*?Dʑsssggggggg>g>b>>>g>bv]~Ftu[«:__숔rɔ..c:G=[$^yy^˙{zʋvgv,' +ÖgggsgsssssggsssBBsssggvgv,'z,q~~qzzx>>>\FFFY_1LT.-|GęH}kDMD~s͑gggggggggvv>v>b>gvvv?xʳ:«Ĉi˛ĩ˵H:^^yyTctF>F0wsgs͑sgs͑ssPsggggv\ӂtqqF'?v>>vqF,F쵴|(@ַĩH-GHĤɈn˞˙ɰզ,ssssggggggg>gvvvvvb>gv]Mq.-T=«=._ցɡޙľHHG[^yy^¨r置Vʂx,,0qxősBsssggsssBBggggqF"t*tFqM?v?~qYL}|J;{V.}.4tFmfgssgggggg>gv>>vgg>gvv]q{HT:cľ{{ɷ.XH.č{,?qqꋂMqősssgsssssPsgvmxʳuDz"UzF~x???qq״({{ɼ4{k{æM'D,ss͑sggggggg>vvvvvg>іxw,zD{ĵH
T:o֮ɮ1˵HT}.ġ{~wqÂw~w,,FFF,̑ssgsPg?x~'U"~x~qqܾ-}.{3O{qq'ggsgggggg>v?m?vі]ÜzHH}Hˈr{{{{{@{{ .H}KrFqqqwø~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ě.[!:cHlGG4U4əH|.r@d@@V'zzzzz1Lč{*qxm??wuC+ƛ+444u_1ވ + +'*D,w~{{zwgsss͑gvx]qq,ddd_{{_{z,~~vxxM~3,t{k.[[||c;}G|4D'VE{{dև'Dɾĩ,~3Ɉ;:c_{h{ɷĞ(ě'z~m?'VճmsssBsssg>v?xM~Ü,z'{__r{__𰇱 +~~?vvv?xM,'*{1쌴«:-=:c˞H¿X=^^y[c䮍LlL֘,qYFz +"t{@֟rֆ"~~~qY"{JTc;1o{{J.;ˍzx>gqUtw\Ősssssssg?x]~ʜ0'{{i_riD~̖vvv?]x~~qʠFn...ĵQTJ˞[.[[^yp)!G.ܙ Q~~qqqY@Vtr跾Fz{ĵ||-˙k.H
J...Hzʖ>mÊ +q]ggsssgxx~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@{֮_,qwqtl!||=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{@rFq~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'Fqqzux\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<͐͐͐sgіꋂ~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,734o{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-}TT{UqztD'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 +.:TX 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{,q0gg>̦ó"UF,,3,zt'zF,ʜttt~gvv?x]~q +kޞH}HJ;
=X}}}GTHz3 +{1@{֮11ƛanU +zmsbbgbgz{ޞlXQu/()yy^.nAuzqqm,~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=$l6lTVg>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:^-Jvx~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ީ.rqxzYÖ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, +tVg>>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,YzUr5n.
=¿ 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,ʜ,'cX[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
ˍdA +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
Hk(ɇ,qq3{ɾޙɮrFx>>\F{{{Vu{{;JJHcHc}HHL4؍DBsg,3*,mqD'ő̖qqĵ$X!rggsggAV{#Jrޛ(֒,~q3,'V{ީěir{tFx\v>>q't_r@{V{@ޛ;..c.cH.؍EŐssss>dEqt*<ggxà' ^-34 +gggsggg"r ĩęƛވވ{̦~q,*ˈ_{F??vѬ\q{E*tt{ɾL˞.HcHHHHHLñ~ssBsssPPsgg\Ü֮{U,tEgggg~UG^^^^^qڍVxgggsgĝ,Vޛĩ5r{r{drFʳFz"{{.L.1r{Fx?\vŦz'ݘzFzr..JHcH
H1ޝ곋gsBBBssggv~"֔ޛV"ÜtEtPgʼu-|^Ryy^Tduv>gggg~,'ލkrqqttt9{dxvw,Fz'tV.HH{]??\>햸w,,FFr....HcH
}HH.-qggssBBssPsgg\,.H}Hޔև +tVYggv>>ÓƝ^yyy}4?>ggs̋'E{k_rq]qqqqqz{{ +zdӪv?q'E{˞Hˍkr{zqM?\g?~Mwwqzַ.HJ.JHHHHcH}H
}HHLH-mgss8s>vqVr.c-GGG-LɇVDtgg>>gvØV|yyyHrFtttxv>>gb͑~q +{{{{hzqqqqzqqwև{?vw*{@{'wxx\v\?m]~Mwqqzr.HccHcHH}
}
HHƤ}mmgssBsgg>vmw.H-
G.VVU*Egvgvv~"^yppy r,z'Fm?vgggggm~qDFz +qqҜz{ɮ{{,]\?FE{ĩ𮇽t'ӂ]~]mm???̖~Mwwwɔ˞...cHccHcHcHc
c.ވTGmgssBBsgg]t.JHc.HHHˈVt,gvvq'V}^yy)=rqq,qvősg̦ÜzDrr{ttkވևqmx~qF'*{Ʃލ_{zʂӋMqqqqw~~q.J.JcHHH}cHHLcG<gsssggv]ƈޛ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.:ƒmggŭu_{{{{{{{{V,wMqz@
^^HޛuFqFqʂvsss͐sgvmʜFD{ěrr:=HĈ{qqqqY'tnniɮ{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?vggssg̖x,ʜ0D{kƩJ
::-T|T}J{{..웍d{t{k𮮇,FU~D{{{r蛩ęĩH=T}{zÂxŐgŪuuHHޡr{@#@ޙޙ褤__j mbssŖqqq0z{{rkL.c}
TG._t9{H}㞛{Ut{{kk{ +z,ÜzV4rĩĩީ[T.~%\?m3 +V"H--ɇV{@W{rrrɾ˞˩kևjk؛ŪgvőgsZ~~,*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*{FqFz30 +{웩ީ
-ľ,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\qtsgggŬ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_ɮ(rdDѪ>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ɮrrr*{{{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,~~HTQruqq'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~~ʜggsBsssb??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{'3ggsb>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.HHJHtU֔{ևm>\\3rr֒UDDDgg>>vv??\?]xw/4V7"#rɮ.
.vzuozqwMM~qzU@{{ƛ֟Dggg͑ggv?~wqFFʂ]q,0F't*rr{{*'*{֮ީ.. +t9֮ɾWވ{Uq?Ѫx]ޔY'DtDqgv?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 |