Browse Source

* hermes moved

git-svn-id: trunk@10003 -
marco 17 years ago
parent
commit
fbb87fe2d8
47 changed files with 18812 additions and 0 deletions
  1. 46 0
      .gitattributes
  2. 2612 0
      packages/hermes/Makefile
  3. 48 0
      packages/hermes/Makefile.fpc
  4. 223 0
      packages/hermes/src/clear.inc
  5. 739 0
      packages/hermes/src/convert.inc
  6. 176 0
      packages/hermes/src/d_32.inc
  7. 62 0
      packages/hermes/src/debug.inc
  8. 82 0
      packages/hermes/src/dither.inc
  9. 482 0
      packages/hermes/src/factconv.inc
  10. 398 0
      packages/hermes/src/factory.inc
  11. 138 0
      packages/hermes/src/format.inc
  12. 42 0
      packages/hermes/src/headp.inc
  13. 40 0
      packages/hermes/src/hermconf.inc
  14. 60 0
      packages/hermes/src/hermdef.inc
  15. 536 0
      packages/hermes/src/hermes.pp
  16. 44 0
      packages/hermes/src/i386/headi386.inc
  17. 20 0
      packages/hermes/src/i386/headmmx.inc
  18. 271 0
      packages/hermes/src/i386/mmx_clr.as
  19. 70 0
      packages/hermes/src/i386/mmx_main.as
  20. 386 0
      packages/hermes/src/i386/mmxp2_32.as
  21. 163 0
      packages/hermes/src/i386/mmxp_32.as
  22. 2059 0
      packages/hermes/src/i386/x8616lut.as
  23. 297 0
      packages/hermes/src/i386/x86_clr.as
  24. 182 0
      packages/hermes/src/i386/x86_main.as
  25. 1154 0
      packages/hermes/src/i386/x86p_16.as
  26. 1043 0
      packages/hermes/src/i386/x86p_32.as
  27. 120 0
      packages/hermes/src/i386/x86p_cpy.as
  28. 230 0
      packages/hermes/src/i386/x86p_i8.as
  29. 116 0
      packages/hermes/src/i386/x86p_s32.as
  30. 42 0
      packages/hermes/src/i386/x86pscpy.as
  31. 212 0
      packages/hermes/src/list.inc
  32. 31 0
      packages/hermes/src/malloc.inc
  33. 795 0
      packages/hermes/src/p_16.inc
  34. 691 0
      packages/hermes/src/p_24.inc
  35. 943 0
      packages/hermes/src/p_32.inc
  36. 171 0
      packages/hermes/src/p_clr.inc
  37. 67 0
      packages/hermes/src/p_cnv.inc
  38. 167 0
      packages/hermes/src/p_cpy.inc
  39. 1118 0
      packages/hermes/src/p_g.inc
  40. 617 0
      packages/hermes/src/p_ga.inc
  41. 119 0
      packages/hermes/src/p_gac.inc
  42. 118 0
      packages/hermes/src/p_gca.inc
  43. 119 0
      packages/hermes/src/p_gcc.inc
  44. 405 0
      packages/hermes/src/p_i8.inc
  45. 899 0
      packages/hermes/src/p_muhmu.inc
  46. 348 0
      packages/hermes/src/palette.inc
  47. 111 0
      packages/hermes/src/utility.inc

+ 46 - 0
.gitattributes

@@ -3762,6 +3762,52 @@ packages/hash/src/md5.pp svneol=native#text/plain
 packages/hash/src/ntlm.pas svneol=native#text/plain
 packages/hash/src/ntlm.pas svneol=native#text/plain
 packages/hash/src/unixcrypt.pas svneol=native#text/plain
 packages/hash/src/unixcrypt.pas svneol=native#text/plain
 packages/hash/src/uuid.pas svneol=native#text/plain
 packages/hash/src/uuid.pas svneol=native#text/plain
+packages/hermes/Makefile svneol=native#text/plain
+packages/hermes/Makefile.fpc svneol=native#text/plain
+packages/hermes/src/clear.inc svneol=native#text/plain
+packages/hermes/src/convert.inc svneol=native#text/plain
+packages/hermes/src/d_32.inc svneol=native#text/plain
+packages/hermes/src/debug.inc svneol=native#text/plain
+packages/hermes/src/dither.inc svneol=native#text/plain
+packages/hermes/src/factconv.inc svneol=native#text/plain
+packages/hermes/src/factory.inc svneol=native#text/plain
+packages/hermes/src/format.inc svneol=native#text/plain
+packages/hermes/src/headp.inc svneol=native#text/plain
+packages/hermes/src/hermconf.inc svneol=native#text/plain
+packages/hermes/src/hermdef.inc svneol=native#text/plain
+packages/hermes/src/hermes.pp svneol=native#text/plain
+packages/hermes/src/i386/headi386.inc -text
+packages/hermes/src/i386/headmmx.inc -text
+packages/hermes/src/i386/mmx_clr.as -text
+packages/hermes/src/i386/mmx_main.as -text
+packages/hermes/src/i386/mmxp2_32.as -text
+packages/hermes/src/i386/mmxp_32.as -text
+packages/hermes/src/i386/x8616lut.as -text
+packages/hermes/src/i386/x86_clr.as -text
+packages/hermes/src/i386/x86_main.as -text
+packages/hermes/src/i386/x86p_16.as -text
+packages/hermes/src/i386/x86p_32.as -text
+packages/hermes/src/i386/x86p_cpy.as -text
+packages/hermes/src/i386/x86p_i8.as -text
+packages/hermes/src/i386/x86p_s32.as -text
+packages/hermes/src/i386/x86pscpy.as -text
+packages/hermes/src/list.inc svneol=native#text/plain
+packages/hermes/src/malloc.inc svneol=native#text/plain
+packages/hermes/src/p_16.inc svneol=native#text/plain
+packages/hermes/src/p_24.inc svneol=native#text/plain
+packages/hermes/src/p_32.inc svneol=native#text/plain
+packages/hermes/src/p_clr.inc svneol=native#text/plain
+packages/hermes/src/p_cnv.inc svneol=native#text/plain
+packages/hermes/src/p_cpy.inc svneol=native#text/plain
+packages/hermes/src/p_g.inc svneol=native#text/plain
+packages/hermes/src/p_ga.inc svneol=native#text/plain
+packages/hermes/src/p_gac.inc svneol=native#text/plain
+packages/hermes/src/p_gca.inc svneol=native#text/plain
+packages/hermes/src/p_gcc.inc svneol=native#text/plain
+packages/hermes/src/p_i8.inc svneol=native#text/plain
+packages/hermes/src/p_muhmu.inc svneol=native#text/plain
+packages/hermes/src/palette.inc svneol=native#text/plain
+packages/hermes/src/utility.inc svneol=native#text/plain
 packages/ibase/Makefile svneol=native#text/plain
 packages/ibase/Makefile svneol=native#text/plain
 packages/ibase/Makefile.fpc svneol=native#text/plain
 packages/ibase/Makefile.fpc svneol=native#text/plain
 packages/ibase/README svneol=native#text/plain
 packages/ibase/README svneol=native#text/plain

+ 2612 - 0
packages/hermes/Makefile

@@ -0,0 +1,2612 @@
+#
+# 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=hermes
+override PACKAGE_VERSION=0.99.5
+I386_LOADERSSRC=src/i386/x86_main.as src/i386/x86p_cpy.as \
+	src/i386/x86pscpy.as src/i386/x86p_16.as \
+	src/i386/x86p_i8.as src/i386/x86_clr.as \
+	src/i386/x86p_32.as src/i386/x86p_s32.as
+ifeq ($(CPU_TARGET),i386)
+CPU_LOADERS=mmx_clr mmxp_32 mmx_main mmxp2_32 hm_i386
+else
+CPU_LOADERS=
+endif
+ifeq ($(FULL_TARGET),i386-linux)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+override TARGET_UNITS+=hermes
+endif
+ifeq ($(FULL_TARGET),i386-linux)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+override TARGET_LOADERS+=$(CPU_LOADERS)
+endif
+ifeq ($(FULL_TARGET),i386-linux)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-linux)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-linux)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+override COMPILER_TARGETDIR+=.
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+override COMPILER_TARGETDIR+=.
+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
+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 
+ifeq ($(FULL_TARGET),i386-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+REQUIRE_PACKAGES_RTL=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
+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 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_loaders
+ifneq ($(TARGET_LOADERS),)
+override ALLTARGET+=fpc_loaders
+override CLEANTARGET+=fpc_loaders_clean
+override INSTALLTARGET+=fpc_loaders_install
+override LOADEROFILES:=$(addsuffix $(OEXT),$(TARGET_LOADERS))
+endif
+%$(OEXT): %$(LOADEREXT)
+ifdef COMPILER_UNITTARGETDIR
+	$(AS) -o $(COMPILER_UNITTARGETDIR)/$*$(OEXT) $<
+else
+	$(AS) -o $*$(OEXT) $<
+endif
+fpc_loaders: $(COMPILER_UNITTARGETDIR) $(LOADEROFILES)
+fpc_loaders_clean:
+ifdef COMPILER_UNITTARGETDIR
+	-$(DEL) $(addprefix $(COMPILER_UNITTARGETDIR)/,$(LOADEROFILES))
+else
+	-$(DEL) $(LOADEROFILES)
+endif
+fpc_loaders_install:
+	$(MKDIR) $(INSTALL_UNITDIR)
+ifdef COMPILER_UNITTARGETDIR
+	$(INSTALL) $(addprefix $(COMPILER_UNITTARGETDIR)/,$(LOADEROFILES)) $(INSTALL_UNITDIR)
+else
+	$(INSTALL) $(LOADEROFILES) $(INSTALL_UNITDIR)
+endif
+.PHONY: fpc_units
+ifneq ($(TARGET_UNITS)$(TARGET_IMPLICITUNITS),)
+override ALLTARGET+=fpc_units
+override UNITPPUFILES=$(addsuffix $(PPUEXT),$(TARGET_UNITS))
+override IMPLICITUNITPPUFILES=$(addsuffix $(PPUEXT),$(TARGET_IMPLICITUNITS))
+override INSTALLPPUFILES+=$(UNITPPUFILES) $(IMPLICITUNITPPUFILES)
+override CLEANPPUFILES+=$(UNITPPUFILES) $(IMPLICITUNITPPUFILES)
+endif
+fpc_units: $(COMPILER_UNITTARGETDIR) $(UNITPPUFILES)
+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:
+mmx_clr$(OEXT):src/$(CPU_TARGET)/mmx_clr.as
+	$(AS) --32 -o $(UNITTARGETDIRPREFIX)mmx_clr$(OEXT) src/$(CPU_TARGET)/mmx_clr.as
+mmxp_32$(OEXT):src/$(CPU_TARGET)/mmxp_32.as
+	$(AS) --32 -o $(UNITTARGETDIRPREFIX)mmxp_32$(OEXT) src/$(CPU_TARGET)/mmxp_32.as
+mmx_main$(OEXT):src/$(CPU_TARGET)/mmx_main.as
+	$(AS) --32 -o $(UNITTARGETDIRPREFIX)mmx_main$(OEXT) src/$(CPU_TARGET)/mmx_main.as
+mmxp2_32$(OEXT):src/$(CPU_TARGET)/mmxp2_32.as
+	$(AS) --32 -o $(UNITTARGETDIRPREFIX)mmxp2_32$(OEXT) src/$(CPU_TARGET)/mmxp2_32.as
+hm_i386$(OEXT): $(I386_LOADERSSRC)
+	$(AS) --32 -o $(UNITTARGETDIRPREFIX)hm_i386$(OEXT) $(I386_LOADERSSRC)

+ 48 - 0
packages/hermes/Makefile.fpc

@@ -0,0 +1,48 @@
+#
+#   Makefile.fpc for Hermes
+#
+
+[package]
+name=hermes
+version=0.99.5
+
+[target]
+units=hermes
+loaders=$(CPU_LOADERS)
+
+[compiler]
+unitdir=
+targetdir=.
+includedir=src
+sourcedir=src tests
+
+[default]
+fpcdir=../..
+
+[rules]
+.NOTPARALLEL:
+mmx_clr$(OEXT):src/$(CPU_TARGET)/mmx_clr.as
+        $(AS) --32 -o $(UNITTARGETDIRPREFIX)mmx_clr$(OEXT) src/$(CPU_TARGET)/mmx_clr.as
+
+mmxp_32$(OEXT):src/$(CPU_TARGET)/mmxp_32.as
+        $(AS) --32 -o $(UNITTARGETDIRPREFIX)mmxp_32$(OEXT) src/$(CPU_TARGET)/mmxp_32.as
+
+mmx_main$(OEXT):src/$(CPU_TARGET)/mmx_main.as
+        $(AS) --32 -o $(UNITTARGETDIRPREFIX)mmx_main$(OEXT) src/$(CPU_TARGET)/mmx_main.as
+
+mmxp2_32$(OEXT):src/$(CPU_TARGET)/mmxp2_32.as
+        $(AS) --32 -o $(UNITTARGETDIRPREFIX)mmxp2_32$(OEXT) src/$(CPU_TARGET)/mmxp2_32.as
+
+hm_i386$(OEXT): $(I386_LOADERSSRC)
+        $(AS) --32 -o $(UNITTARGETDIRPREFIX)hm_i386$(OEXT) $(I386_LOADERSSRC)
+
+[prerules]
+I386_LOADERSSRC=src/i386/x86_main.as src/i386/x86p_cpy.as \
+        src/i386/x86pscpy.as src/i386/x86p_16.as \
+        src/i386/x86p_i8.as src/i386/x86_clr.as \
+        src/i386/x86p_32.as src/i386/x86p_s32.as
+ifeq ($(CPU_TARGET),i386)
+CPU_LOADERS=mmx_clr mmxp_32 mmx_main mmxp2_32 hm_i386
+else
+CPU_LOADERS=
+endif

+ 223 - 0
packages/hermes/src/clear.inc

@@ -0,0 +1,223 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+{Function Hermes_ClearerInstance : THermesHandle;
+Procedure Hermes_ClearerReturn(handle : THermesHandle);
+Function Hermes_ClearerRequest(handle : THermesHandle; format : PHermesFormat) : Boolean;
+Function Hermes_ClearerClear(handle : THermesHandle; pixels : Pointer;
+                             x1, y1, width, height, pitch : Integer;
+                             r, g, b : int32; index : char8) : Boolean;}
+
+Type
+  PClearerInstance = ^TClearerInstance;
+  TClearerInstance = Record
+    format : PHermesFormat;
+    func : THermesClearPtr;
+  End;
+
+Const
+{ClearerList is a list of TClearerInstance}
+  ClearerList : PHermesList = Nil;
+  CLEARrefcount : Integer = 0;
+  ClearCurrenthandle : THermesHandle = 0;
+
+Function Hermes_ClearerInstance : THermesHandle;
+
+Var
+  element : PHermesListElement;
+  newinstance : PClearerInstance;
+
+Begin
+  If CLEARrefcount = 0 Then
+  Begin
+    ClearerList := Hermes_ListNew;
+    If ClearerList = Nil Then
+    Begin
+      Hermes_ClearerInstance := 0;
+      Exit;
+    End;
+  End;
+  element := Hermes_ListElementNew(ClearCurrenthandle + 1);
+  If element = Nil Then
+  Begin
+    Hermes_ClearerInstance := 0;
+    Exit;
+  End;
+  newinstance := malloc(SizeOf(TClearerInstance));
+  If newinstance = Nil Then
+  Begin
+    Hermes_ClearerInstance := 0;
+    Exit;
+  End;
+  newinstance^.func := Nil;
+  newinstance^.format := Hermes_FormatNewEmpty;
+  If newinstance^.format = Nil Then
+  Begin
+    Hermes_ClearerInstance := 0;
+    Exit;
+  End;
+  element^.data := newinstance;
+  Hermes_ListAdd(ClearerList, element);
+  Inc(CLEARrefcount);
+  Inc(ClearCurrenthandle);
+  Hermes_ClearerInstance := ClearCurrenthandle;
+End;
+
+Procedure Hermes_ClearerFreeHandleCallback(q : Pointer);
+
+Begin
+  free(PClearerInstance(q)^.format);
+End;
+
+Procedure Hermes_ClearerReturn(handle : THermesHandle);
+
+Var
+  element : PHermesListElement;
+  instance : PClearerInstance;
+
+Begin
+  Dec(CLEARrefcount);
+  If Hermes_ListDeleteElement(ClearerList, handle, @Hermes_ClearerFreeHandleCallback) = False Then
+    Exit;
+  If CLEARrefcount = 0 Then
+  Begin
+    { Dirty fix: Free the format pointers in all the clearer instances }
+    { The list functions need updating to allow member deletion! }
+    element := ClearerList^.first;
+    While element <> Nil Do
+    Begin
+      instance := element^.data;
+      free(instance^.format);
+      element := element^.next;
+    End;
+    Hermes_ListDestroy(ClearerList);
+  End;
+End;
+
+Function Hermes_ClearerRequest(handle : THermesHandle; format : PHermesFormat) : Boolean;
+
+Var
+  element : PHermesListElement;
+  clr : PClearerInstance;
+  i : Integer;
+
+Begin
+  { Look up this clearer in the list }
+  element := Hermes_ListLookup(ClearerList, handle);
+  If element = Nil Then
+  Begin
+    Hermes_ClearerRequest := False;
+    Exit;
+  End;
+  clr := element^.data;
+
+  { If the clearer is the same, return 1 }
+  If Hermes_FormatEquals(clr^.format, format) Then
+  Begin
+    Hermes_ClearerRequest := True;
+    Exit;
+  End;
+
+  { Otherwise look for a new clearer }
+  clr^.func := Nil;
+  For i := 0 To numClearers - 1 Do
+  Begin
+    If Clearers[i]^.bits = format^.bits Then
+    Begin
+      clr^.func := Clearers[i]^.func;
+      Hermes_FormatCopy(format, clr^.format);
+      Hermes_ClearerRequest := True;
+      Exit;
+    End;
+  End;
+  Hermes_ClearerRequest := False;
+End;
+
+Function Hermes_ClearerClear(handle : THermesHandle; pixels : Pointer;
+                             x1, y1, width, height, pitch : Integer;
+                             r, g, b : int32; index : char8) : Boolean;
+
+Var
+  element : PHermesListElement;
+  info : THermesGenericInfo;
+  clr : PClearerInstance;
+  pixelval, d_r, d_g, d_b, d_a : int32;
+  iface : THermesClearInterface;
+
+Begin
+  If (height <= 0) Or (width <= 0) Then
+  Begin
+    Hermes_ClearerClear := True;
+    Exit;
+  End;
+
+  { Look up this clearer in the list }
+  element := Hermes_ListLookup(ClearerList, handle);
+  If (element = Nil) Or (element^.data = Nil) Then
+  Begin
+    Hermes_ClearerClear := False;
+    Exit;
+  End;
+
+  { Get clearer instance from list element data }
+  clr := element^.data;
+
+  { No conversion function assigned }
+  If clr^.func = Nil Then
+  Begin
+    Hermes_ClearerClear := False;
+    Exit;
+  End;
+
+  If clr^.format^.indexed Then
+    pixelval := index
+  Else
+  Begin
+    Hermes_Calculate_Generic_Info(24, 16, 8, 32,
+                                  Hermes_Topbit(clr^.format^.r),
+                                  Hermes_Topbit(clr^.format^.g),
+                                  Hermes_Topbit(clr^.format^.b),
+                                  Hermes_Topbit(clr^.format^.a), @info);
+    pixelval := (index Shl 24) Or (r Shl 16) Or (g Shl 8) Or b;
+    d_r := ((pixelval Shr info.r_right) Shl info.r_left) And clr^.format^.r;
+    d_g := ((pixelval Shr info.g_right) Shl info.g_left) And clr^.format^.g;
+    d_b := ((pixelval Shr info.b_right) Shl info.b_left) And clr^.format^.b;
+    d_a := ((pixelval Shr info.a_right) Shl info.a_left) And clr^.format^.a;
+    pixelval := d_r Or d_g Or d_b Or d_a;
+  End;
+  iface.dest := pixels;
+  Inc(iface.dest, y1*pitch + x1*(clr^.format^.bits Shr 3));
+
+  iface.width := width;
+  iface.height := height;
+  iface.add := pitch - width * (clr^.format^.bits Shr 3);
+
+  iface.value := pixelval;
+
+  { Optimization }
+  If iface.add = 0 Then
+  Begin
+    iface.width := iface.width * iface.height;
+    iface.height := 1;
+  End;
+
+  clr^.func(@iface);
+  Hermes_ClearerClear := True;
+End;

+ 739 - 0
packages/hermes/src/convert.inc

@@ -0,0 +1,739 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+
+{Function Hermes_ConverterInstance(flags : DWord) : THermesHandle;
+Procedure Hermes_ConverterReturn(handle : THermesHandle);}
+
+Var
+{ ConverterList is a list of HermesConverter* }
+  ConverterList : ^PHermesConverter;
+  ConvertCurrenthandle : THermesHandle;
+
+Const
+  lastConverter : Integer = 0;                { Array size, one beyond end }
+  CONVERTrefcount : Integer = 0;
+
+Function Hermes_ConverterInstance(flags : DWord) : THermesHandle;
+
+Var
+  i : Integer;
+  newinstance : PHermesConverter;
+  newlist : ^PHermesConverter;
+
+Begin
+  { Initialising, allocate initial size array of converters }
+  If CONVERTrefcount = 0 Then
+  Begin
+    ConverterList := malloc(SizeOf(PHermesConverter) * HERMES_INITIAL);
+    If ConverterList = Nil Then
+    Begin
+      Hermes_ConverterInstance := 0;
+      Exit;
+    End;
+    lastConverter := HERMES_INITIAL;
+    ConvertCurrenthandle := 1;
+    For i := 0 To lastConverter - 1 Do
+      ConverterList[i] := Nil;
+{    DEBUG_PRINT("Creating dynamic array(convert.c:57), size %d\n",HERMES_INITIAL)}
+  End;
+
+  { Uh oh, arrary too small, time for growth }
+  If ConvertCurrenthandle = lastConverter Then
+  Begin
+    { I'm told realloc isn't completely portable !? Let's do it by hand }
+    newlist := malloc(SizeOf(PHermesConverter)*(lastConverter+HERMES_GROWTH));
+    If newlist = Nil Then
+    Begin
+      Hermes_ConverterInstance := 0;
+      Exit;
+    End;
+    { Copy converter pointers }
+    For i := 0 To lastConverter - 1 Do
+      newlist[i] := ConverterList[i];
+    free(ConverterList);
+    { Assign new list to old one }
+    ConverterList := newlist;
+    Inc(lastConverter, HERMES_GROWTH);
+{    DEBUG_PRINT("Growing dynamic array, new size %d\n",lastConverter)}
+  End;
+
+  { Create a HermesConverter }
+  newinstance := malloc(sizeof(THermesConverter));
+  If newinstance = Nil Then
+  Begin
+    Hermes_ConverterInstance := 0;
+    Exit;
+  End;
+
+  { Zero it out }
+  newinstance^.loopnormal := Nil;
+  newinstance^.loopstretch := Nil;
+  newinstance^.normal := Nil;
+  newinstance^.stretch := Nil;
+  newinstance^.dither := Nil;
+  newinstance^.ditherstretch := Nil;
+  newinstance^.flags := flags;
+  FillChar(newinstance^.source, 0, SizeOf(THermesFormat));
+  FillChar(newinstance^.dest, 0, SizeOf(THermesFormat));
+
+  ConverterList[ConvertCurrenthandle] := newinstance;
+
+  Inc(CONVERTrefcount);
+  Inc(ConvertCurrenthandle);
+
+  Hermes_ConverterInstance := ConvertCurrenthandle - 1;
+End;
+
+Procedure Hermes_ConverterReturn(handle : THermesHandle);
+
+Begin
+  If (handle < 0) Or (handle >= lastConverter) Then
+    Exit;
+
+  { Adjust reference count }
+  Dec(CONVERTrefcount);
+
+  If ConverterList[handle] <> Nil Then
+  Begin
+    free(ConverterList[handle]);
+    ConverterList[handle] := Nil;
+  End;
+
+  { No more references, deinitialise }
+  If CONVERTrefcount = 0 Then
+  Begin
+    If ConverterList <> Nil Then
+    Begin
+      free(ConverterList);
+      ConverterList := Nil;
+    End;
+    ConvertCurrenthandle := 0;
+    lastConverter := 0;
+  End;
+End;
+
+Function Hermes_ConverterRequest(handle : THermesHandle;
+                                 source, dest : PHermesFormat) : Boolean;
+
+Var
+  searchlist : Integer;
+  i : Integer;
+  found : Boolean;
+  cnv : PHermesConverter;
+
+Begin
+{  DebugMSG('Hermes_ConverterRequest(' + C2Str(source^.bits)
+   + ',' + C2Str(source^.r) + ',' + C2Str(source^.g) + ',' +
+   C2Str(source^.b) + ';' + C2Str(dest^.bits)
+   + ',' + C2Str(dest^.r) + ',' + C2Str(dest^.g) + ',' +
+   C2Str(dest^.b) + ')');}
+
+  Hermes_ConverterRequest := False;
+  searchlist := 0;
+  i := 0;
+  found := False;
+  { Check array ranges }
+  If (handle < 0) Or (handle >= lastConverter) Then
+    Exit;
+  If ConverterList[handle] = Nil Then
+    Exit;
+  cnv := ConverterList[handle];
+
+  { Cache repeated requests of the same conversion }
+  If Hermes_FormatEquals(source, @ConverterList[handle]^.source) And
+     Hermes_FormatEquals(dest, @ConverterList[handle]^.dest) Then
+  Begin
+    Hermes_ConverterRequest := True;
+    Exit;
+  End;
+
+  { Clear the generic converter flag }
+  cnv^.flags := cnv^.flags And (Not HERMES_CONVERT_GENERIC);
+
+  { If the source and destination are equal, use copy routines }
+  If Hermes_FormatEquals(source, dest) Then
+  Begin
+{    DebugMSG('format equals!');}
+    If ((source^.bits And 7) <> 0) Or (source^.bits > 32) Or
+       (source^.bits = 0) Then
+      Exit;
+    i := (source^.bits Shr 3) - 1;
+    If equalConverters[i] = Nil Then
+      Exit;
+    Hermes_FormatCopy(source, @cnv^.source);
+    Hermes_FormatCopy(dest, @cnv^.dest);
+    cnv^.loopnormal := equalConverters[i]^.loopnormal;
+    cnv^.loopstretch := equalConverters[i]^.loopstretch;
+    cnv^.normal := equalConverters[i]^.normal;
+    cnv^.stretch := equalConverters[i]^.stretch;
+    Hermes_ConverterRequest := True;
+    Exit;
+  End;
+
+  { Start looking for specialised converters }
+  searchlist := $ff;
+  Case source^.bits Of
+    32 : If (source^.r = $ff0000) And (source^.g = $ff00) And (source^.b = $ff) Then
+           searchlist := 0
+         Else
+           If (source^.r = ($ff Shl 20)) And
+              (source^.g = ($ff Shl 10)) And
+              (source^.b = $ff) Then
+             searchlist := 3;
+    24 : If (source^.r = $ff0000) And (source^.g = $ff00) And (source^.b = $ff) Then
+           searchlist := 1;
+    16 : If (source^.r = $f800) And (source^.g = $7e0) And (source^.b = $1f) Then
+           searchlist := 2;
+     8 : If source^.indexed Then
+           searchlist := 4;
+  End;
+
+  { We can use a quicker loop for 8 bit }
+  If searchlist <> $ff Then
+    If source^.bits = 8 Then
+    Begin
+      For i := 0 To numConverters[searchlist] - 1 Do
+        If standardConverters[searchlist][i] <> Nil Then
+          If dest^.bits = standardConverters[searchlist][i]^.dest.bits Then
+          Begin
+            Hermes_FormatCopy(source, @cnv^.source);
+            Hermes_FormatCopy(dest, @cnv^.dest);
+
+            cnv^.loopnormal := standardConverters[searchlist][i]^.loopnormal;
+            cnv^.loopstretch := standardConverters[searchlist][i]^.loopstretch;
+
+            cnv^.normal := standardConverters[searchlist][i]^.normal;
+            cnv^.stretch := standardConverters[searchlist][i]^.stretch;
+
+            cnv^.dither := standardConverters[searchlist][i]^.dither;
+            cnv^.ditherstretch := standardConverters[searchlist][i]^.ditherstretch;
+
+            Hermes_ConverterRequest := True;
+            Exit;
+          End
+;
+    End
+    Else
+      For i := 0 To numConverters[searchlist] - 1 Do
+        If standardConverters[searchlist][i] <> Nil Then
+          If Hermes_FormatEquals(@standardConverters[searchlist][i]^.source, source) And
+             Hermes_FormatEquals(@standardConverters[searchlist][i]^.dest, dest) Then
+          Begin
+            Hermes_FormatCopy(source, @cnv^.source);
+            Hermes_FormatCopy(dest, @cnv^.dest);
+
+            cnv^.loopnormal := standardConverters[searchlist][i]^.loopnormal;
+            cnv^.loopstretch := standardConverters[searchlist][i]^.loopstretch;
+
+            cnv^.normal := standardConverters[searchlist][i]^.normal;
+            cnv^.stretch := standardConverters[searchlist][i]^.stretch;
+
+            cnv^.dither := standardConverters[searchlist][i]^.dither;
+            cnv^.ditherstretch := standardConverters[searchlist][i]^.ditherstretch;
+
+            Hermes_ConverterRequest := True;
+            Exit;
+          End;
+
+
+  { Otherwise find a generic converter }
+{  DebugMSG('looking for a generic converter!');}
+
+
+  cnv^.loopnormal := Nil;
+  cnv^.loopstretch := Nil;
+  cnv^.dither := Nil;
+  cnv^.ditherstretch := Nil;
+  cnv^.flags := cnv^.flags Or HERMES_CONVERT_GENERIC;
+
+
+  { Generic routines implement whole converters not scanline converters,
+    assign placeholders }
+
+  cnv^.normal := @NotApplicable;
+  cnv^.stretch := @NotApplicable;
+
+  found := False;
+
+{
+        Converting rules:
+
+        C -> C
+        C -> A
+
+        A -> O, A -> A
+        A -> C
+
+        O -> O , A, C are the same
+}
+
+  If source^.has_colorkey And dest^.has_colorkey Then { Ck -> Ck }
+    Case source^.bits Of
+      32 : Case dest^.bits Of
+        32 : Begin
+          cnv^.loopnormal := @ConvertP_Generic32_C_Generic32_C;
+          cnv^.loopstretch := @ConvertP_Generic32_C_Generic32_C_S;
+          found := True;
+        End;
+        24 : Begin
+          cnv^.loopnormal := @ConvertP_Generic32_C_Generic24_C;
+          found := True;
+        End;
+        16 : Begin
+          cnv^.loopnormal := @ConvertP_Generic32_C_Generic16_C;
+          cnv^.loopstretch := @ConvertP_Generic32_C_Generic16_C_S;
+          found := True;
+        End;
+        8 : Begin
+          cnv^.loopnormal := @ConvertP_Generic32_C_Generic8_C;
+          found := True;
+        End;
+      End;
+      24 : Case dest^.bits Of
+        32 : Begin
+          cnv^.loopnormal := @ConvertP_Generic24_C_Generic32_C;
+          found := True;
+        End;
+        24 : Begin
+          cnv^.loopnormal := @ConvertP_Generic24_C_Generic24_C;
+          found := True;
+        End;
+        16 : Begin
+          cnv^.loopnormal := @ConvertP_Generic24_C_Generic16_C;
+          found := True;
+        End;
+        8 : Begin
+          cnv^.loopnormal := @ConvertP_Generic24_C_Generic8_C;
+          found := True;
+        End;
+      End;
+      16 : Case dest^.bits Of
+        32 : Begin
+          cnv^.loopnormal := @ConvertP_Generic16_C_Generic32_C;
+          found := True;
+        End;
+        24 : Begin
+          cnv^.loopnormal := @ConvertP_Generic16_C_Generic24_C;
+          found := True;
+        End;
+        16 : Begin
+          cnv^.loopnormal := @ConvertP_Generic16_C_Generic16_C;
+          found := True;
+        End;
+        8 : Begin
+          cnv^.loopnormal := @ConvertP_Generic16_C_Generic8_C;
+          found := True;
+        End;
+      End;
+    End
+  Else
+    If source^.has_colorkey And (dest^.a <> 0) Then { Ck -> A }
+      Case source^.bits Of
+        32 : Case dest^.bits Of
+          32 : Begin
+            cnv^.loopnormal := @ConvertP_Generic32_C_Generic32_A;
+            cnv^.loopstretch := @ConvertP_Generic32_C_Generic32_A_S;
+            found := True;
+          End;
+          24 : Begin
+            cnv^.loopnormal := @ConvertP_Generic32_C_Generic24_A;
+            found := True;
+          End;
+          16 : Begin
+            cnv^.loopnormal := @ConvertP_Generic32_C_Generic16_A;
+            cnv^.loopstretch := @ConvertP_Generic32_C_Generic16_A_S;
+            found := True;
+          End;
+          8 : Begin
+            cnv^.loopnormal := @ConvertP_Generic32_C_Generic8_A;
+            found := True;
+          End;
+        End;
+        24 : Case dest^.bits Of
+          32 : Begin
+            cnv^.loopnormal := @ConvertP_Generic24_C_Generic32_A;
+            found := True;
+          End;
+          24 : Begin
+            cnv^.loopnormal := @ConvertP_Generic24_C_Generic24_A;
+            found := True;
+          End;
+          16 : Begin
+            cnv^.loopnormal := @ConvertP_Generic24_C_Generic16_A;
+            found := True;
+          End;
+          8 : Begin
+            cnv^.loopnormal := @ConvertP_Generic24_C_Generic8_A;
+            found := True;
+          End;
+        End;
+        16 : Case dest^.bits Of
+          32 : Begin
+            cnv^.loopnormal := @ConvertP_Generic16_C_Generic32_A;
+            found := True;
+          End;
+          24 : Begin
+            cnv^.loopnormal := @ConvertP_Generic16_C_Generic24_A;
+            found := True;
+          End;
+          16 : Begin
+            cnv^.loopnormal := @ConvertP_Generic16_C_Generic16_A;
+            found := True;
+          End;
+          8 : Begin
+            cnv^.loopnormal := @ConvertP_Generic16_C_Generic8_A;
+            found := True;
+          End;
+        End;
+      End
+    Else
+      If (source^.a <> 0) And dest^.has_colorkey Then { A -> Ck }
+        Case source^.bits Of
+          32 : Case dest^.bits Of
+            32 : Begin
+              cnv^.loopnormal := @ConvertP_Generic32_A_Generic32_C;
+              cnv^.loopstretch := @ConvertP_Generic32_A_Generic32_C_S;
+              found := True;
+            End;
+            24 : Begin
+              cnv^.loopnormal := @ConvertP_Generic32_A_Generic24_C;
+              found := True;
+            End;
+            16 : Begin
+              cnv^.loopnormal := @ConvertP_Generic32_A_Generic16_C;
+              cnv^.loopnormal := @ConvertP_Generic32_A_Generic16_C_S;
+              found := True;
+            End;
+            8 : Begin
+              cnv^.loopnormal := @ConvertP_Generic32_A_Generic8_C;
+              found := True;
+            End;
+          End;
+          24 : Case dest^.bits Of
+            32 : Begin
+              cnv^.loopnormal := @ConvertP_Generic24_A_Generic32_C;
+              found := True;
+            End;
+            24 : Begin
+              cnv^.loopnormal := @ConvertP_Generic24_A_Generic24_C;
+              found := True;
+            End;
+            16 : Begin
+              cnv^.loopnormal := @ConvertP_Generic24_A_Generic16_C;
+              found := True;
+            End;
+            8 : Begin
+              cnv^.loopnormal := @ConvertP_Generic24_A_Generic8_C;
+              found := True;
+            End;
+          End;
+          16 : Case dest^.bits Of
+            32 : Begin
+              cnv^.loopnormal := @ConvertP_Generic16_A_Generic32_C;
+              found := True;
+            End;
+            24 : Begin
+              cnv^.loopnormal := @ConvertP_Generic16_A_Generic24_C;
+              found := True;
+            End;
+            16 : Begin
+              cnv^.loopnormal := @ConvertP_Generic16_A_Generic16_C;
+              found := True;
+            End;
+            8 : Begin
+              cnv^.loopnormal := @ConvertP_Generic16_A_Generic8_C;
+              found := True;
+            End;
+          End;
+        End
+      Else
+        If (source^.a <> 0) And (dest^.a <> 0) Then { A -> A }
+          Case source^.bits Of
+            32 : Case dest^.bits Of
+              32 : Begin
+                cnv^.loopnormal := @ConvertP_Generic32_A_Generic32_A;
+                cnv^.loopstretch := @ConvertP_Generic32_A_Generic32_A_S;
+                found := True;
+              End;
+              24 : Begin
+                cnv^.loopnormal := @ConvertP_Generic32_A_Generic24_A;
+                found := True;
+              End;
+              16 : Begin
+                cnv^.loopnormal := @ConvertP_Generic32_A_Generic16_A;
+                cnv^.loopstretch := @ConvertP_Generic32_A_Generic16_A_S;
+                found := True;
+              End;
+              8 : Begin
+                cnv^.loopnormal := @ConvertP_Generic32_A_Generic8_A;
+                found := True;
+              End;
+            End;
+            24 : Case dest^.bits Of
+              32 : Begin
+                cnv^.loopnormal := @ConvertP_Generic24_A_Generic32_A;
+                found := True;
+              End;
+              24 : Begin
+                cnv^.loopnormal := @ConvertP_Generic24_A_Generic24_A;
+                found := True;
+              End;
+              16 : Begin
+                cnv^.loopnormal := @ConvertP_Generic24_A_Generic16_A;
+                found := True;
+              End;
+              8 : Begin
+                cnv^.loopnormal := @ConvertP_Generic24_A_Generic8_A;
+                found := True;
+              End;
+            End;
+            16 : Case dest^.bits Of
+              32 : Begin
+                cnv^.loopnormal := @ConvertP_Generic16_A_Generic32_A;
+                found := True;
+              End;
+              24 : Begin
+                cnv^.loopnormal := @ConvertP_Generic16_A_Generic24_A;
+                found := True;
+              End;
+              16 : Begin
+                cnv^.loopnormal := @ConvertP_Generic16_A_Generic16_A;
+                found := True;
+              End;
+              8 : Begin
+                cnv^.loopnormal := @ConvertP_Generic16_A_Generic8_A;
+                found := True;
+              End;
+            End;
+          End
+        Else { O->O, O->A, A->O, Ck->O, O->Ck }
+          Case source^.bits Of
+            32 : Case dest^.bits Of
+              32 : Begin
+                cnv^.loopnormal := @ConvertP_Generic32_Generic32;
+                cnv^.loopstretch := @ConvertP_Generic32_Generic32_S;
+                found := True;
+              End;
+              24 : Begin
+                cnv^.loopnormal := @ConvertP_Generic32_Generic24;
+                cnv^.loopstretch := @ConvertP_Generic32_Generic24_S;
+                found := True;
+              End;
+              16 : Begin
+                cnv^.loopnormal := @ConvertP_Generic32_Generic16;
+                cnv^.loopstretch := @ConvertP_Generic32_Generic16_S;
+                found := True;
+              End;
+              8 : Begin
+                cnv^.loopnormal := @ConvertP_Generic32_Generic8;
+                cnv^.loopstretch := @ConvertP_Generic32_Generic8_S;
+                found := True;
+              End;
+            End;
+            24 : Case dest^.bits Of
+              32 : Begin
+                cnv^.loopnormal := @ConvertP_Generic24_Generic32;
+                cnv^.loopstretch := @ConvertP_Generic24_Generic32_S;
+                found := True;
+              End;
+              24 : Begin
+                cnv^.loopnormal := @ConvertP_Generic24_Generic24;
+                cnv^.loopstretch := @ConvertP_Generic24_Generic24_S;
+                found := True;
+              End;
+              16 : Begin
+                cnv^.loopnormal := @ConvertP_Generic24_Generic16;
+                cnv^.loopstretch := @ConvertP_Generic24_Generic16_S;
+                found := True;
+              End;
+              8 : Begin
+                cnv^.loopnormal := @ConvertP_Generic24_Generic8;
+                cnv^.loopstretch := @ConvertP_Generic24_Generic8_S;
+                found := True;
+              End;
+            End;
+            16 : Case dest^.bits Of
+              32 : Begin
+                cnv^.loopnormal := @ConvertP_Generic16_Generic32;
+                cnv^.loopstretch := @ConvertP_Generic16_Generic32_S;
+                found := True;
+              End;
+              24 : Begin
+                cnv^.loopnormal := @ConvertP_Generic16_Generic24;
+                cnv^.loopstretch := @ConvertP_Generic16_Generic24_S;
+                found := True;
+              End;
+              16 : Begin
+                cnv^.loopnormal := @ConvertP_Generic16_Generic16;
+                cnv^.loopstretch := @ConvertP_Generic16_Generic16_S;
+                found := True;
+              End;
+              8 : Begin
+                cnv^.loopnormal := @ConvertP_Generic16_Generic8;
+                cnv^.loopstretch := @ConvertP_Generic16_Generic8_S;
+                found := True;
+              End;
+            End;
+          End;
+
+  If found Then
+  Begin
+    Hermes_FormatCopy(source, @cnv^.source);
+    Hermes_FormatCopy(dest, @cnv^.dest);
+
+    Hermes_ConverterRequest := True;
+    Exit;
+  End;
+
+  DebugMSG('no converter found!!!');
+  { No converter found, fail }
+  Hermes_ConverterRequest := False;
+End;
+
+Function Hermes_ConverterPalette(handle, sourcepal, destpal : THermesHandle) : Boolean;
+
+Begin
+{  DebugMSG('Hermes_ConverterPalette('+C2Str(sourcepal)+','+C2Str(destpal)+')');}
+  Hermes_ConverterPalette := False;
+  If (handle < 0) Or (handle >= lastConverter) Then
+    Exit;
+  If ConverterList[handle] = Nil Then
+    Exit;
+
+  { Fail silently if not indexed colour format }
+  If Not ConverterList[handle]^.source.indexed Then
+  Begin
+    ConverterList[handle]^.lookup := Nil;
+    Hermes_ConverterPalette := True;
+    Exit;
+  End;
+
+  ConverterList[handle]^.lookup :=
+    Hermes_PaletteGetTable(sourcepal, @ConverterList[handle]^.dest);
+
+  If ConverterList[handle]^.lookup = Nil Then
+    Exit;
+
+  Hermes_ConverterPalette := True;
+End;
+
+Function Hermes_ConverterCopy(handle : THermesHandle; s_pixels : Pointer;
+                              s_x, s_y, s_width, s_height, s_pitch : Integer;
+                              d_pixels : Pointer; d_x, d_y, d_width,
+                              d_height, d_pitch : Integer) : Boolean;
+
+Var
+  cnv : PHermesConverter;
+  iface : THermesConverterInterface;
+
+Begin
+  Hermes_ConverterCopy := False;
+  If (handle < 0) Or (handle >= lastConverter) Then
+    Exit;
+  cnv := ConverterList[handle];
+  If cnv = Nil Then
+    Exit;
+
+  { Returns success if height or width is zero. This is debatable.. ! }
+  If (s_width <= 0) Or (s_height <= 0) Or (d_width <= 0) Or (d_height <= 0) Then
+  Begin
+    Hermes_ConverterCopy := True;
+    Exit;
+  End;
+
+  iface.s_pixels := s_pixels;
+  iface.s_width := s_width;
+  iface.s_height := s_height;
+  iface.s_add := s_pitch - s_width * (cnv^.source.bits Shr 3);
+  iface.s_pitch := s_pitch;
+
+  iface.d_pixels := d_pixels;
+  iface.d_width := d_width;
+  iface.d_height := d_height;
+  iface.d_add := d_pitch - d_width*(cnv^.dest.bits Shr 3);
+  iface.d_pitch := d_pitch;
+
+  Inc(iface.s_pixels, s_y * s_pitch + s_x * (cnv^.source.bits Shr 3));
+  Inc(iface.d_pixels, d_y * d_pitch + d_x * (cnv^.dest.bits Shr 3));
+
+  iface.s_has_colorkey := cnv^.source.has_colorkey;
+  iface.d_has_colorkey := cnv^.dest.has_colorkey;
+  iface.s_colorkey := cnv^.source.colorkey;
+  iface.d_colorkey := cnv^.dest.colorkey;
+
+  iface.lookup := cnv^.lookup;
+
+
+  { For generic converters, do some extra setup (find shifts, etc.)
+    TODO: Move that out of here and in the request routine ! }
+  If (cnv^.flags And HERMES_CONVERT_GENERIC) <> 0 Then
+  Begin
+    Hermes_Calculate_Generic_Info(Hermes_Topbit(cnv^.source.r),
+                                  Hermes_Topbit(cnv^.source.g),
+                                  Hermes_Topbit(cnv^.source.b),
+                                  Hermes_Topbit(cnv^.source.a),
+                                  Hermes_Topbit(cnv^.dest.r),
+                                  Hermes_Topbit(cnv^.dest.g),
+                                  Hermes_Topbit(cnv^.dest.b),
+                                  Hermes_Topbit(cnv^.dest.a),
+                                  @iface.info);
+    iface.mask_r := cnv^.dest.r;
+    iface.mask_g := cnv^.dest.g;
+    iface.mask_b := cnv^.dest.b;
+    iface.mask_a := cnv^.dest.a;
+  End;
+
+  { Check for dithering. This should not be in here but in request as well }
+  If (cnv^.flags And HERMES_CONVERT_DITHER) <> 0 Then
+  Begin
+    { If there is a ditherer, use it else fall back to normal }
+    If cnv^.dither <> Nil Then
+      cnv^.loopnormal := cnv^.dither;
+  End;
+
+  { Normal conversion }
+  If (s_width = d_width) And (s_height = d_height) Then
+  Begin
+    If (cnv^.normal = Nil) Or (cnv^.loopnormal = Nil) Then
+      Exit;
+    { Optimization
+    If (iface.s_add = 0) And (iface.d_add = 0) Then
+    Begin
+      iface.s_width := iface.s_width * s_height;
+      iface.d_width := iface.d_width * d_height;
+      iface.s_height := 1;
+      iface.d_height := 1;
+    End;}
+    iface.func := cnv^.normal;
+    cnv^.loopnormal(@iface);
+    Hermes_ConverterCopy := True;
+    Exit;
+  End
+  { Stretch conversion }
+  Else
+  Begin
+    If (cnv^.stretch = Nil) Or (cnv^.loopstretch = Nil) Then
+      Exit;
+    iface.func := cnv^.stretch;
+    cnv^.loopstretch(@iface);
+  End;
+  Hermes_ConverterCopy := True;
+End;

+ 176 - 0
packages/hermes/src/d_32.inc

@@ -0,0 +1,176 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+{
+   32 bit to * dithered converters for the HERMES library
+   Copyright (c) 1998 Christian Nentwich ([email protected])
+   This source code is licensed under the GNU LGPL
+  
+   Please refer to the file COPYING.LIB contained in the distribution for
+   licensing conditions
+}
+
+Procedure ConvertP_32rgb888_16rgb565_dither(iface : PHermesConverterInterface); CDecl;
+
+Var
+  source, dest : Pchar8;
+  d_pixel : int32;
+  y, count : LongInt;
+
+Begin
+  y := 0;
+  source := iface^.s_pixels;
+  dest := iface^.d_pixels;
+  While y < iface^.d_height Do
+  Begin
+    { Get counter for this scanline }
+    count := iface^.d_width;
+
+    { Check first pixel alignment, correct if necessary }
+    If (PtrUInt(iface^.d_pixels) And 3) <> 0 Then
+    Begin
+      Pshort16(dest)^ := 
+        DitherTab_r565_44[count And 3, y And 3, (Pint32(source)^ Shr 16) And $ff] Or
+	DitherTab_g565_44[count And 3, y And 3, (Pint32(source)^ Shr 8) And $ff] Or
+	DitherTab_b565_44[count And 3, y And 3, Pint32(source)^ And $ff];
+
+      Inc(source, 4);
+      Inc(dest, 2);
+      Dec(count);
+    End;
+
+    { Two pixels at a time loop }
+    While count > 1 Do
+    Begin
+      d_pixel :=
+        DitherTab_r565_44[count And 3, y And 3, (Pint32(source)^ Shr 16) And $ff] Or
+	DitherTab_g565_44[count And 3, y And 3, (Pint32(source)^ Shr 8) And $ff] Or
+	DitherTab_b565_44[count And 3, y And 3, Pint32(source)^ And $ff];
+
+      Inc(source, 4);
+      Dec(count);
+
+      d_pixel := d_pixel Or ((
+        DitherTab_r565_44[count And 3, y And 3, (Pint32(source)^ Shr 16) And $ff] Or
+	DitherTab_g565_44[count And 3, y And 3, (Pint32(source)^ Shr 8) And $ff] Or
+	DitherTab_b565_44[count And 3, y And 3, Pint32(source)^ And $ff]) Shl 16);
+
+      Dec(count);
+      Inc(source, 4);
+
+      Pint32(dest)^ := d_pixel;
+
+      Inc(dest, 4);
+    End;
+
+    { Convert the odd trailing pixel }
+    If (iface^.d_width And 1) <> 0 Then
+    Begin
+      Pshort16(dest)^ :=
+        DitherTab_r565_44[count And 3, y And 3, (Pint32(source)^ Shr 16) And $ff] Or
+	DitherTab_g565_44[count And 3, y And 3, (Pint32(source)^ Shr 8) And $ff] Or
+	DitherTab_b565_44[count And 3, y And 3, Pint32(source)^ And $ff];
+
+      Inc(source, 4);
+      Inc(dest, 2);
+    End;
+
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+
+    Inc(y);
+  End;
+End;
+
+Procedure ConvertP_32rgb888_8rgb332_dither(iface : PHermesConverterInterface); CDecl;
+
+Var
+  source, dest : Pchar8;
+  d_pixel : int32;
+  y, count : LongInt;
+
+Begin
+  y := 0;
+  source := iface^.s_pixels;
+  dest := iface^.d_pixels;
+ 
+  While y < iface^.d_height Do
+  Begin
+    { Get counter for this scanline }
+    count := iface^.d_width;
+
+
+    { TODO: alignment loop }
+
+
+    { Convert 4 pixels at a time }
+    While count > 3 Do
+    Begin
+      d_pixel :=
+        DitherTab_r332_44[count And 3, y And 3, (Pint32(source)^ Shr 16) And $ff] Or
+	DitherTab_g332_44[count And 3, y And 3, (Pint32(source)^ Shr 8) And $ff] Or
+	DitherTab_b332_44[count And 3, y And 3, Pint32(source)^ And $ff];
+      Dec(count);
+      Inc(source, 4);
+
+      d_pixel := d_pixel Or ((
+        DitherTab_r332_44[count And 3, y And 3, (Pint32(source)^ Shr 16) And $ff] Or
+	DitherTab_g332_44[count And 3, y And 3, (Pint32(source)^ Shr 8) And $ff] Or
+	DitherTab_b332_44[count And 3, y And 3, Pint32(source)^ And $ff]) Shl 8);
+      Dec(count);
+      Inc(source, 4);
+
+      d_pixel := d_pixel Or ((
+        DitherTab_r332_44[count And 3, y And 3, (Pint32(source)^ Shr 16) And $ff] Or
+	DitherTab_g332_44[count And 3, y And 3, (Pint32(source)^ Shr 8) And $ff] Or
+	DitherTab_b332_44[count And 3, y And 3, Pint32(source)^ And $ff]) Shl 16);
+      Dec(count);
+      Inc(source, 4);
+
+      d_pixel := d_pixel Or ((
+        DitherTab_r332_44[count And 3, y And 3, (Pint32(source)^ Shr 16) And $ff] Or
+	DitherTab_g332_44[count And 3, y And 3, (Pint32(source)^ Shr 8) And $ff] Or
+	DitherTab_b332_44[count And 3, y And 3, Pint32(source)^ And $ff]) Shl 24);
+      Dec(count);
+      Inc(source, 4);
+
+      Pint32(dest)^ := d_pixel;
+      Inc(dest, 4);
+    End;
+
+    { Write trailing pixels }
+    While count <> 0 Do
+    Begin
+      Dec(count);
+      dest^ := 
+        DitherTab_r332_44[count And 3, y And 3, (Pint32(source)^ Shr 16) And $ff] Or
+	DitherTab_g332_44[count And 3, y And 3, (Pint32(source)^ Shr 8) And $ff] Or
+	DitherTab_b332_44[count And 3, y And 3, Pint32(source)^ And $ff];
+
+      Inc(source, 4);
+      Inc(dest);
+    End;
+
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+
+    Inc(y);
+  End;
+End;

+ 62 - 0
packages/hermes/src/debug.inc

@@ -0,0 +1,62 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+Function C2Str(Q : Integer) : String;
+
+Var
+  S : String;
+
+Begin
+  Str(Q, S);
+  C2Str := S;
+End;
+
+Procedure DebugInit;
+
+{Var
+  F : Text;}
+
+Begin
+{  ASSign(F, 'debug.txt');
+  Rewrite(F);
+  Close(F);}
+End;
+
+Procedure DebugMSG(S : String);
+
+Var
+  F : Text;
+
+Begin
+  ASSign(F, 'debug.txt');
+  {$I-}
+  Append(F);
+  {$I+}
+  If IOResult <> 0 Then
+  Begin
+    {$I-}
+    Rewrite(F);
+    {$I+}
+    If IOResult <> 0 Then
+      Exit;
+  End;
+  Writeln(F, S);
+  Close(F);
+End;

+ 82 - 0
packages/hermes/src/dither.inc

@@ -0,0 +1,82 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+{ Everything in here (C)1998 The Rasterman }
+
+{ Rasterman's dither matrix }
+
+Const
+  DitherMatrix_44 : Array[0..3, 0..3] Of char8 = (
+    (0, 4, 1, 5),
+    (6, 2, 7, 3),
+    (1, 5, 0, 4),
+    (7, 3, 6, 2));
+
+Var
+  DitherTab_r565_44 : Array[0..3, 0..3, 0..255] Of short16;
+  DitherTab_g565_44 : Array[0..3, 0..3, 0..255] Of short16;
+  DitherTab_b565_44 : Array[0..3, 0..3, 0..255] Of short16;
+
+  DitherTab_r332_44 : Array[0..3, 0..3, 0..255] Of char8;
+  DitherTab_g332_44 : Array[0..3, 0..3, 0..255] Of char8;
+  DitherTab_b332_44 : Array[0..3, 0..3, 0..255] Of char8;
+
+Procedure Dither_SetupMatrices;
+
+Var
+  i, x, y : LongInt;
+
+Begin  
+  For y := 0 To 3 Do
+    For x := 0 To 3 Do
+      For i := 0 To 255 Do
+      Begin
+        If (DitherMatrix_44[x, y] < (i And $7)) And (i < (256 - 8)) Then
+	Begin
+	  DitherTab_r565_44[x, y, i] := ((i + 8) And $f8) Shl 8;
+	  DitherTab_r332_44[x, y, i] := ((i + 8) And $e0);
+	End
+	Else
+	Begin
+	  DitherTab_r565_44[x, y, i] := (i And $f8) Shl 8;
+	  DitherTab_r332_44[x, y, i] := i And $e0;
+	End;
+        If (DitherMatrix_44[x, y] < ((i And $3) Shl 1)) And (i < (256 - 4)) Then
+	Begin
+	  DitherTab_g565_44[x, y, i] := (((i + 4) And $fc) Shl 8) Shr 5;
+	  DitherTab_g332_44[x, y, i] := ((i + 4) And $e0) Shr 3;
+	End
+	Else
+	Begin
+	  DitherTab_g565_44[x, y, i] := ((i And $fc) Shl 8) Shr 5;
+	  DitherTab_g332_44[x, y, i] := (i And $e0) Shr 3;
+	End;
+        If (DitherMatrix_44[x, y] < (i And $7)) And (i < (256 - 8)) Then
+	Begin
+	  DitherTab_b565_44[x, y, i] := (((i + 8) And $f8) Shl 16) Shr 19;
+	  DitherTab_b332_44[x, y, i] := ((i + 8) Shr 6) And $3;
+	End
+	Else
+	Begin
+	  DitherTab_b565_44[x, y, i] := ((i And $f8) Shl 16) Shr 19;
+	  DitherTab_b332_44[x, y, i] := (i Shr 6) And $3;
+	End;
+      End;
+End;

+ 482 - 0
packages/hermes/src/factconv.inc

@@ -0,0 +1,482 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+
+{  Placeholder converter. This is for things like 8 bit converters that have
+   one main loop and NO scanline conversion function as opposed to most others
+   which use the generic loop.
+   There needs to be a function assigned to the scanline loop however,
+   otherwise the converter will fail a test in Convert.c. This is the easiest
+   way. Do NOT use NotApplicable as NotYetImplemented ! }
+Procedure NotApplicable(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Begin
+  If source <> Nil Then;
+  If dest <> Nil Then;
+  If count <> 0 Then;
+  If inc_source <> 0 Then;
+End;
+
+{  Factory converter array, holds ALL converters available from HERMES. Note
+   that converters have to be assigned IN ORDER of priority for processors
+   that can run different converters.
+   Thus, for an Intel MMX Pentium, the order would be:
+
+      - MMX converters
+      - X86 converters
+      - Pascal converters
+
+   If someone wrote a P2 or P3 converter, if would be added even further up. }
+
+Const
+  Factory_NumConverters = 45
+  {$IFDEF I386_ASSEMBLER}+27{$ENDIF I386_ASSEMBLER};
+
+  Factory_Converters : Array[0..Factory_NumConverters - 1] Of THermesFactoryStruct =
+(
+{$IFDEF I386_ASSEMBLER}
+  { ------ From 32 RGB 888 - MMX PENTIUM II ---- }
+  (s_bits:32;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:24;d_idx:False;d_r:$ff0000;d_g:$ff00;d_b:$ff;d_a:0;
+   loopnormal:@ConvertMMX;loopstretch:Nil;normal:@ConvertMMXpII32_24RGB888;
+   stretch:Nil;dither:Nil;ditherstretch:Nil;processor:PROC_MMX_PENTIUM),
+
+  (s_bits:32;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:16;d_idx:False;d_r:$f800;d_g:$7e0;d_b:$1f;d_a:0;
+   loopnormal:@ConvertMMX;loopstretch:Nil;normal:@ConvertMMXpII32_16RGB565;
+   stretch:Nil;dither:Nil;ditherstretch:Nil;processor:PROC_MMX_PENTIUM),
+
+  (s_bits:32;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:16;d_idx:False;d_r:$1f;d_g:$7e0;d_b:$f800;d_a:0;
+   loopnormal:@ConvertMMX;loopstretch:Nil;normal:@ConvertMMXpII32_16BGR565;
+   stretch:Nil;dither:Nil;ditherstretch:Nil;processor:PROC_MMX_PENTIUM),
+
+  (s_bits:32;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:16;d_idx:False;d_r:$7c00;d_g:$3e0;d_b:$1f;d_a:0;
+   loopnormal:@ConvertMMX;loopstretch:Nil;normal:@ConvertMMXpII32_16RGB555;
+   stretch:Nil;dither:Nil;ditherstretch:Nil;processor:PROC_MMX_PENTIUM),
+
+  (s_bits:32;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:16;d_idx:False;d_r:$1f;d_g:$3e0;d_b:$7c00;d_a:0;
+   loopnormal:@ConvertMMX;loopstretch:Nil;normal:@ConvertMMXpII32_16BGR555;
+   stretch:Nil;dither:Nil;ditherstretch:Nil;processor:PROC_MMX_PENTIUM),
+
+  { ------ From 32 RGB 888 - MMX PENTIUM ------- }
+  (s_bits:32;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:16;d_idx:False;d_r:$7c00;d_g:$3e0;d_b:$1f;d_a:0;
+   loopnormal:@ConvertMMX;loopstretch:Nil;normal:@ConvertMMXpII32_16RGB555;
+   stretch:Nil;dither:Nil;ditherstretch:Nil;processor:PROC_MMX_PENTIUM),
+
+  { ------ From 32 RGB 888 - X86 PENTIUM ------- }
+  (s_bits:32;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:32;d_idx:False;d_r:$ff;d_g:$ff00;d_b:$ff0000;d_a:0;
+   loopnormal:@ConvertX86;loopstretch:Nil;normal:@ConvertX86p32_32BGR888;
+   stretch:Nil;dither:Nil;ditherstretch:Nil;processor:PROC_X86_PENTIUM),
+
+  (s_bits:32;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:32;d_idx:False;d_r:$ff000000;d_g:$ff0000;d_b:$ff00;d_a:$ff;
+   loopnormal:@ConvertX86;loopstretch:Nil;normal:@ConvertX86p32_32RGBA888;
+   stretch:Nil;dither:Nil;ditherstretch:Nil;processor:PROC_X86_PENTIUM),
+
+  (s_bits:32;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:32;d_idx:False;d_r:$ff00;d_g:$ff0000;d_b:$ff000000;d_a:$ff;
+   loopnormal:@ConvertX86;loopstretch:Nil;normal:@ConvertX86p32_32BGRA888;
+   stretch:Nil;dither:Nil;ditherstretch:Nil;processor:PROC_X86_PENTIUM),
+
+  (s_bits:32;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:24;d_idx:False;d_r:$ff0000;d_g:$ff00;d_b:$ff;d_a:0;
+   loopnormal:@ConvertX86;loopstretch:Nil;normal:@ConvertX86p32_24RGB888;
+   stretch:Nil;dither:Nil;ditherstretch:Nil;processor:PROC_X86_PENTIUM),
+
+  (s_bits:32;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:24;d_idx:False;d_r:$ff;d_g:$ff00;d_b:$ff0000;d_a:0;
+   loopnormal:@ConvertX86;loopstretch:Nil;normal:@ConvertX86p32_24BGR888;
+   stretch:Nil;dither:Nil;ditherstretch:Nil;processor:PROC_X86_PENTIUM),
+
+  (s_bits:32;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:16;d_idx:False;d_r:$f800;d_g:$7e0;d_b:$1f;d_a:0;
+   loopnormal:@ConvertX86;loopstretch:@ConvertX86Stretch;
+   normal:@ConvertX86p32_16RGB565;stretch:@ConvertX86p32_16RGB565_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_X86_PENTIUM),
+
+  (s_bits:32;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:16;d_idx:False;d_r:$1f;d_g:$7e0;d_b:$f800;d_a:0;
+   loopnormal:@ConvertX86;loopstretch:Nil;normal:@ConvertX86p32_16BGR565;
+   stretch:Nil;dither:Nil;ditherstretch:Nil;processor:PROC_X86_PENTIUM),
+
+  (s_bits:32;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:16;d_idx:False;d_r:$7c00;d_g:$3e0;d_b:$1f;d_a:0;
+   loopnormal:@ConvertX86;loopstretch:Nil;normal:@ConvertX86p32_16RGB555;
+   stretch:Nil;dither:Nil;ditherstretch:Nil;processor:PROC_X86_PENTIUM),
+
+  (s_bits:32;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:16;d_idx:False;d_r:$1f;d_g:$3e0;d_b:$7c00;d_a:0;
+   loopnormal:@ConvertX86;loopstretch:Nil;normal:@ConvertX86p32_16BGR555;
+   stretch:Nil;dither:Nil;ditherstretch:Nil;processor:PROC_X86_PENTIUM),
+
+  (s_bits:32;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:8;d_idx:False;d_r:$e0;d_g:$1c;d_b:$3;d_a:0;
+   loopnormal:@ConvertX86;loopstretch:Nil;normal:@ConvertX86p32_8RGB332;
+   stretch:Nil;dither:Nil;ditherstretch:Nil;processor:PROC_X86_PENTIUM),
+
+  { ------ From 16 RGB 565 - X86 PENTIUM ------- }
+  (s_bits:16;s_idx:False;s_r:$f800;s_g:$7e0;s_b:$1f;s_a:0;
+   d_bits:32;d_idx:False;d_r:$ff0000;d_g:$ff00;d_b:$ff;d_a:0;
+   loopnormal:@ConvertX86;loopstretch:Nil;normal:@ConvertX86p16_32RGB888;
+   stretch:Nil;dither:Nil;ditherstretch:Nil;processor:PROC_X86_PENTIUM),
+
+  (s_bits:16;s_idx:False;s_r:$f800;s_g:$7e0;s_b:$1f;s_a:0;
+   d_bits:32;d_idx:False;d_r:$ff;d_g:$ff00;d_b:$ff0000;d_a:0;
+   loopnormal:@ConvertX86;loopstretch:Nil;normal:@ConvertX86p16_32BGR888;
+   stretch:Nil;dither:Nil;ditherstretch:Nil;processor:PROC_X86_PENTIUM),
+
+  (s_bits:16;s_idx:False;s_r:$f800;s_g:$7e0;s_b:$1f;s_a:0;
+   d_bits:32;d_idx:False;d_r:$ff000000;d_g:$ff0000;d_b:$ff00;d_a:$ff;
+   loopnormal:@ConvertX86;loopstretch:Nil;normal:@ConvertX86p16_32RGBA888;
+   stretch:Nil;dither:Nil;ditherstretch:Nil;processor:PROC_X86_PENTIUM),
+
+  (s_bits:16;s_idx:False;s_r:$f800;s_g:$7e0;s_b:$1f;s_a:0;
+   d_bits:32;d_idx:False;d_r:$ff00;d_g:$ff0000;d_b:$ff000000;d_a:$ff;
+   loopnormal:@ConvertX86;loopstretch:Nil;normal:@ConvertX86p16_32BGRA888;
+   stretch:Nil;dither:Nil;ditherstretch:Nil;processor:PROC_X86_PENTIUM),
+
+  (s_bits:16;s_idx:False;s_r:$f800;s_g:$7e0;s_b:$1f;s_a:0;
+   d_bits:24;d_idx:False;d_r:$ff0000;d_g:$ff00;d_b:$ff;d_a:0;
+   loopnormal:@ConvertX86;loopstretch:Nil;normal:@ConvertX86p16_24RGB888;
+   stretch:Nil;dither:Nil;ditherstretch:Nil;processor:PROC_X86_PENTIUM),
+
+  (s_bits:16;s_idx:False;s_r:$f800;s_g:$7e0;s_b:$1f;s_a:0;
+   d_bits:24;d_idx:False;d_r:$ff;d_g:$ff00;d_b:$ff0000;d_a:0;
+   loopnormal:@ConvertX86;loopstretch:Nil;normal:@ConvertX86p16_24BGR888;
+   stretch:Nil;dither:Nil;ditherstretch:Nil;processor:PROC_X86_PENTIUM),
+
+  (s_bits:16;s_idx:False;s_r:$f800;s_g:$7e0;s_b:$1f;s_a:0;
+   d_bits:16;d_idx:False;d_r:$1f;d_g:$7e0;d_b:$f800;d_a:0;
+   loopnormal:@ConvertX86;loopstretch:Nil;normal:@ConvertX86p16_16BGR565;
+   stretch:Nil;dither:Nil;ditherstretch:Nil;processor:PROC_X86_PENTIUM),
+
+  (s_bits:16;s_idx:False;s_r:$f800;s_g:$7e0;s_b:$1f;s_a:0;
+   d_bits:16;d_idx:False;d_r:$7c00;d_g:$3e0;d_b:$1f;d_a:0;
+   loopnormal:@ConvertX86;loopstretch:Nil;normal:@ConvertX86p16_16RGB555;
+   stretch:Nil;dither:Nil;ditherstretch:Nil;processor:PROC_X86_PENTIUM),
+
+  (s_bits:16;s_idx:False;s_r:$f800;s_g:$7e0;s_b:$1f;s_a:0;
+   d_bits:16;d_idx:False;d_r:$1f;d_g:$3e0;d_b:$7c00;d_a:0;
+   loopnormal:@ConvertX86;loopstretch:Nil;normal:@ConvertX86p16_16BGR555;
+   stretch:Nil;dither:Nil;ditherstretch:Nil;processor:PROC_X86_PENTIUM),
+
+  (s_bits:16;s_idx:False;s_r:$f800;s_g:$7e0;s_b:$1f;s_a:0;
+   d_bits:8;d_idx:False;d_r:$e0;d_g:$1c;d_b:$3;d_a:0;
+   loopnormal:@ConvertX86;loopstretch:Nil;normal:@ConvertX86p16_8RGB332;
+   stretch:Nil;dither:Nil;ditherstretch:Nil;processor:PROC_X86_PENTIUM),
+
+  (s_bits:8;s_idx:True;s_r:0;s_g:0;s_b:0;s_a:0;
+   d_bits:16;d_idx:False;d_r:0;d_g:0;d_b:0;d_a:0;
+   loopnormal:@ConvertX86;loopstretch:Nil;normal:@ConvertX86pI8_16;
+   stretch:Nil;dither:Nil;ditherstretch:Nil;processor:PROC_X86_PENTIUM),
+{$ENDIF I386_ASSEMBLER}
+
+  { ------ From 32 RGBA 8888 ---- }
+  {
+  (s_bits:32;s_idx:False;s_r:$ff000000;s_g:$ff0000;s_b:$ff00;s_a:$ff;
+   d_bits:32;d_idx:False;d_r:$ff000000;d_g:$ff0000;d_b:$ff00;d_a:$ff;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_32rgb888_32bgr888;stretch:@ConvertP_32rgb888_32bgr888_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+  }
+
+  { ------ From 32 RGB 888 ------- }
+
+  (s_bits:32;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:32;d_idx:False;d_r:$ff;d_g:$ff00;d_b:$ff0000;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_32rgb888_32bgr888;stretch:@ConvertP_32rgb888_32bgr888_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:32;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:32;d_idx:False;d_r:$ff000000;d_g:$ff0000;d_b:$ff00;d_a:$ff;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_32rgb888_32rgba888;stretch:@ConvertP_32rgb888_32rgba888_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:32;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:32;d_idx:False;d_r:$ff00;d_g:$ff0000;d_b:$ff000000;d_a:$ff;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_32rgb888_32bgra888;stretch:@ConvertP_32rgb888_32bgra888_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:32;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:24;d_idx:False;d_r:$ff0000;d_g:$ff00;d_b:$ff;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_32rgb888_24rgb888;stretch:@ConvertP_32rgb888_24rgb888_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:32;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:24;d_idx:False;d_r:$ff;d_g:$ff00;d_b:$ff0000;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_32rgb888_24bgr888;stretch:@ConvertP_32rgb888_24bgr888_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:32;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:16;d_idx:False;d_r:$f800;d_g:$7e0;d_b:$1f;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_32rgb888_16rgb565;stretch:@ConvertP_32rgb888_16rgb565_S;
+   dither:@ConvertP_32rgb888_16rgb565_dither;ditherstretch:Nil;
+   processor:PROC_GENERIC),
+
+  (s_bits:32;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:16;d_idx:False;d_r:$1f;d_g:$7e0;d_b:$f800;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_32rgb888_16bgr565;stretch:@ConvertP_32rgb888_16bgr565_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:32;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:16;d_idx:False;d_r:$7c00;d_g:$3e0;d_b:$1f;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_32rgb888_16rgb555;stretch:@ConvertP_32rgb888_16rgb555_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:32;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:16;d_idx:False;d_r:$1f;d_g:$3e0;d_b:$7c00;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_32rgb888_16bgr555;stretch:@ConvertP_32rgb888_16bgr555_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:32;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:8;d_idx:False;d_r:$e0;d_g:$1c;d_b:$3;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_32rgb888_8rgb332;stretch:@ConvertP_32rgb888_8rgb332_S;
+   dither:@ConvertP_32rgb888_8rgb332_dither;
+   ditherstretch:Nil;processor:PROC_GENERIC),
+
+ { ------ From 32 RGB MUHMU ------- }
+  (s_bits:32;s_idx:False;s_r:$ff Shl 20;s_g:$ff Shl 10;s_b:$ff;s_a:0;
+   d_bits:32;d_idx:False;d_r:$ff0000;d_g:$ff00;d_b:$ff;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_muhmu32_32rgb888;stretch:@ConvertP_muhmu32_32rgb888_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:32;s_idx:False;s_r:$ff Shl 20;s_g:$ff Shl 10;s_b:$ff;s_a:0;
+   d_bits:32;d_idx:False;d_r:$ff;d_g:$ff00;d_b:$ff0000;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_muhmu32_32bgr888;stretch:@ConvertP_muhmu32_32bgr888_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:32;s_idx:False;s_r:$ff Shl 20;s_g:$ff Shl 10;s_b:$ff;s_a:0;
+   d_bits:32;d_idx:False;d_r:$ff000000;d_g:$ff0000;d_b:$ff00;d_a:$ff;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_muhmu32_32rgba888;stretch:@ConvertP_muhmu32_32rgba888_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:32;s_idx:False;s_r:$ff Shl 20;s_g:$ff Shl 10;s_b:$ff;s_a:0;
+   d_bits:32;d_idx:False;d_r:$ff00;d_g:$ff0000;d_b:$ff000000;d_a:$ff;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_muhmu32_32bgra888;stretch:@ConvertP_muhmu32_32bgra888_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:32;s_idx:False;s_r:$ff Shl 20;s_g:$ff Shl 10;s_b:$ff;s_a:0;
+   d_bits:24;d_idx:False;d_r:$ff0000;d_g:$ff00;d_b:$ff;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_muhmu32_24rgb888;stretch:@ConvertP_muhmu32_24rgb888_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:32;s_idx:False;s_r:$ff Shl 20;s_g:$ff Shl 10;s_b:$ff;s_a:0;
+   d_bits:24;d_idx:False;d_r:$ff;d_g:$ff00;d_b:$ff0000;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_muhmu32_24bgr888;stretch:@ConvertP_muhmu32_24bgr888_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:32;s_idx:False;s_r:$ff Shl 20;s_g:$ff Shl 10;s_b:$ff;s_a:0;
+   d_bits:16;d_idx:False;d_r:$f800;d_g:$7e0;d_b:$1f;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_muhmu32_16rgb565;stretch:@ConvertP_muhmu32_16rgb565_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:32;s_idx:False;s_r:$ff Shl 20;s_g:$ff Shl 10;s_b:$ff;s_a:0;
+   d_bits:16;d_idx:False;d_r:$1f;d_g:$7e0;d_b:$f800;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_muhmu32_16bgr565;stretch:@ConvertP_muhmu32_16bgr565_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:32;s_idx:False;s_r:$ff Shl 20;s_g:$ff Shl 10;s_b:$ff;s_a:0;
+   d_bits:16;d_idx:False;d_r:$7c00;d_g:$3e0;d_b:$1f;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_muhmu32_16rgb555;stretch:@ConvertP_muhmu32_16rgb555_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:32;s_idx:False;s_r:$ff Shl 20;s_g:$ff Shl 10;s_b:$ff;s_a:0;
+   d_bits:16;d_idx:False;d_r:$1f;d_g:$3e0;d_b:$7c00;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_muhmu32_16bgr555;stretch:@ConvertP_muhmu32_16bgr555_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:32;s_idx:False;s_r:$ff Shl 20;s_g:$ff Shl 10;s_b:$ff;s_a:0;
+   d_bits:8;d_idx:False;d_r:$e0;d_g:$1c;d_b:$3;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_muhmu32_8rgb332;stretch:@ConvertP_muhmu32_8rgb332_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  { ------ From 24 RGB 888 ------- }
+  (s_bits:24;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:32;d_idx:False;d_r:$ff0000;d_g:$ff00;d_b:$ff;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_24rgb888_32rgb888;stretch:@ConvertP_24rgb888_32rgb888_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:24;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:32;d_idx:False;d_r:$ff;d_g:$ff00;d_b:$ff0000;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_24rgb888_32bgr888;stretch:@ConvertP_24rgb888_32bgr888_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:24;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:32;d_idx:False;d_r:$ff000000;d_g:$ff0000;d_b:$ff00;d_a:$ff;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_24rgb888_32rgba888;stretch:@ConvertP_24rgb888_32rgba888_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:24;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:32;d_idx:False;d_r:$ff00;d_g:$ff0000;d_b:$ff000000;d_a:$ff;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_24rgb888_32bgra888;stretch:@ConvertP_24rgb888_32bgra888_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:24;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:24;d_idx:False;d_r:$ff;d_g:$ff00;d_b:$ff0000;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_24rgb888_24bgr888;stretch:@ConvertP_24rgb888_24bgr888_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:24;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:16;d_idx:False;d_r:$f800;d_g:$7e0;d_b:$1f;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_24rgb888_16rgb565;stretch:@ConvertP_24rgb888_16rgb565_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:24;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:16;d_idx:False;d_r:$1f;d_g:$7e0;d_b:$f800;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_24rgb888_16bgr565;stretch:@ConvertP_24rgb888_16bgr565_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:24;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:16;d_idx:False;d_r:$7c00;d_g:$3e0;d_b:$1f;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_24rgb888_16rgb555;stretch:@ConvertP_24rgb888_16rgb555_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:24;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:16;d_idx:False;d_r:$1f;d_g:$3e0;d_b:$7c00;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_24rgb888_16bgr555;stretch:@ConvertP_24rgb888_16bgr555_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:24;s_idx:False;s_r:$ff0000;s_g:$ff00;s_b:$ff;s_a:0;
+   d_bits:8;d_idx:False;d_r:$e0;d_g:$1c;d_b:$3;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_24rgb888_8rgb332;stretch:@ConvertP_24rgb888_8rgb332_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  { ------ From 16 RGB 565 ------- }
+  (s_bits:16;s_idx:False;s_r:$f800;s_g:$7e0;s_b:$1f;s_a:0;
+   d_bits:32;d_idx:False;d_r:$ff0000;d_g:$ff00;d_b:$ff;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_16rgb565_32rgb888;stretch:@ConvertP_16rgb565_32rgb888_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:16;s_idx:False;s_r:$f800;s_g:$7e0;s_b:$1f;s_a:0;
+   d_bits:32;d_idx:False;d_r:$ff;d_g:$ff00;d_b:$ff0000;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_16rgb565_32bgr888;stretch:@ConvertP_16rgb565_32bgr888_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:16;s_idx:False;s_r:$f800;s_g:$7e0;s_b:$1f;s_a:0;
+   d_bits:32;d_idx:False;d_r:$ff000000;d_g:$ff0000;d_b:$ff00;d_a:$ff;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_16rgb565_32rgba888;stretch:@ConvertP_16rgb565_32rgba888_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:16;s_idx:False;s_r:$f800;s_g:$7e0;s_b:$1f;s_a:0;
+   d_bits:32;d_idx:False;d_r:$ff00;d_g:$ff0000;d_b:$ff000000;d_a:$ff;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_16rgb565_32bgra888;stretch:@ConvertP_16rgb565_32bgra888_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:16;s_idx:False;s_r:$f800;s_g:$7e0;s_b:$1f;s_a:0;
+   d_bits:24;d_idx:False;d_r:$ff0000;d_g:$ff00;d_b:$ff;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_16rgb565_24rgb888;stretch:@ConvertP_16rgb565_24rgb888_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:16;s_idx:False;s_r:$f800;s_g:$7e0;s_b:$1f;s_a:0;
+   d_bits:24;d_idx:False;d_r:$ff;d_g:$ff00;d_b:$ff0000;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_16rgb565_24bgr888;stretch:@ConvertP_16rgb565_24bgr888_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:16;s_idx:False;s_r:$f800;s_g:$7e0;s_b:$1f;s_a:0;
+   d_bits:16;d_idx:False;d_r:$1f;d_g:$7e0;d_b:$f800;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_16rgb565_16bgr565;stretch:@ConvertP_16rgb565_16bgr565_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:16;s_idx:False;s_r:$f800;s_g:$7e0;s_b:$1f;s_a:0;
+   d_bits:16;d_idx:False;d_r:$7c00;d_g:$3e0;d_b:$1f;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_16rgb565_16rgb555;stretch:@ConvertP_16rgb565_16rgb555_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:16;s_idx:False;s_r:$f800;s_g:$7e0;s_b:$1f;s_a:0;
+   d_bits:16;d_idx:False;d_r:$1f;d_g:$3e0;d_b:$7c00;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_16rgb565_16bgr555;stretch:@ConvertP_16rgb565_16bgr555_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:16;s_idx:False;s_r:$f800;s_g:$7e0;s_b:$1f;s_a:0;
+   d_bits:8;d_idx:False;d_r:$e0;d_g:$1c;d_b:$3;d_a:0;
+   loopnormal:@ConvertP;loopstretch:@ConvertPStretch;
+   normal:@ConvertP_16rgb565_8rgb332;stretch:@ConvertP_16rgb565_8rgb332_S;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  { ------ From 8 bit INDEXED ------- }
+  (s_bits:8;s_idx:True;s_r:0;s_g:0;s_b:0;s_a:0;
+   d_bits:32;d_idx:False;d_r:0;d_g:0;d_b:0;d_a:0;
+   loopnormal:@ConvertP_index8_32;loopstretch:@ConvertP_index8_32_S;
+   normal:@NotApplicable;stretch:@NotApplicable;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:8;s_idx:True;s_r:0;s_g:0;s_b:0;s_a:0;
+   d_bits:24;d_idx:False;d_r:0;d_g:0;d_b:0;d_a:0;
+   loopnormal:@ConvertP_index8_24;loopstretch:@ConvertP_index8_24_S;
+   normal:@NotApplicable;stretch:@NotApplicable;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:8;s_idx:True;s_r:0;s_g:0;s_b:0;s_a:0;
+   d_bits:16;d_idx:False;d_r:0;d_g:0;d_b:0;d_a:0;
+   loopnormal:@ConvertP_index8_16;loopstretch:@ConvertP_index8_16_S;
+   normal:@NotApplicable;stretch:@NotApplicable;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC),
+
+  (s_bits:8;s_idx:True;s_r:0;s_g:0;s_b:0;s_a:0;
+   d_bits:8;d_idx:False;d_r:0;d_g:0;d_b:0;d_a:0;
+   loopnormal:@ConvertP_index8_8;loopstretch:@ConvertP_index8_8_S;
+   normal:@NotApplicable;stretch:@NotApplicable;
+   dither:Nil;ditherstretch:Nil;processor:PROC_GENERIC)
+);

+ 398 - 0
packages/hermes/src/factory.inc

@@ -0,0 +1,398 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+Var
+  Processor : Integer;
+
+Procedure Hermes_Factory_Init;
+
+Var
+  res : Integer;
+
+Begin
+  res := 0;
+  Processor := PROC_GENERIC;
+
+  {$IFDEF I386_ASSEMBLER}
+    Processor := Processor Or PROC_X86_PENTIUM;{There are no others at the moment}
+    res := Hermes_X86_CPU;
+    If (res And $800000) <> 0 Then
+    Begin
+//      Writeln('mmx disabled for debugging');
+      Processor := Processor Or PROC_MMX_PENTIUM;
+{      Writeln('mmx!');}
+    End;
+  {$ENDIF I386_ASSEMBLER}
+End;
+
+Function Hermes_Factory_getClearer(bits : int32) : PHermesClearer;
+
+Var
+  tmp : PHermesClearer;
+
+Begin
+  { Try different processors in order of priority..
+    Note that for this to work, an MMX processor has to have both MMX and
+    X86 flags }
+  tmp := malloc(SizeOf(THermesClearer));
+  If tmp = Nil Then
+  Begin
+    Hermes_Factory_getClearer := Nil;
+    Exit;
+  End;
+
+  tmp^.bits := bits;
+  Hermes_Factory_getClearer := tmp;
+
+  {$IFDEF I386_ASSEMBLER}
+    If (Processor And PROC_MMX_PENTIUM) <> 0 Then
+      Case bits Of
+        32 : Begin
+          tmp^.func := @ClearMMX_32;
+          Exit;
+        End;
+        24 : ;
+        16 : Begin
+          tmp^.func := @ClearMMX_16;
+          Exit;
+        End;
+        8 : Begin
+          tmp^.func := @ClearMMX_8;
+          Exit;
+        End;
+      End;
+
+    If (Processor And PROC_X86_PENTIUM) <> 0 Then
+      Case bits Of
+        32 : Begin
+          tmp^.func := @ClearX86_32;
+          Exit;
+        End;
+        24 : ;
+        16 : Begin
+          tmp^.func := @ClearX86_16;
+          Exit;
+        End;
+        8 : Begin
+          tmp^.func := @ClearX86_8;
+          Exit;
+        End;
+      End;
+  {$ENDIF I386_ASSEMBLER}
+
+  Case bits Of
+    32 : Begin
+      tmp^.func := @ClearP_32;
+      Exit;
+    End;
+    24 : Begin
+      tmp^.func := @ClearP_24;
+      Exit;
+    End;
+    16 : Begin
+      tmp^.func := @ClearP_16;
+      Exit;
+    End;
+    8 : Begin
+      tmp^.func := @ClearP_8;
+      Exit;
+    End;
+    Else
+    Begin
+      free(tmp);
+      Hermes_Factory_getClearer := Nil;
+    End;
+  End;
+End;
+
+Function Hermes_Factory_getConverter(source, dest : PHermesFormat) : PHermesConverter;
+
+Var
+  tmp : PHermesConverter;
+  i : Integer;
+  found : Boolean;
+
+Begin
+  found := False;
+
+  tmp := malloc(SizeOf(THermesConverter));
+  If tmp = Nil Then
+  Begin
+    Hermes_Factory_getConverter := Nil;
+    Exit;
+  End;
+
+  { Set all conversion routines to nil }
+  tmp^.loopnormal := Nil;
+  tmp^.loopstretch := Nil;
+  tmp^.normal := Nil;
+  tmp^.stretch := Nil;
+  tmp^.dither := Nil;
+  tmp^.ditherstretch := Nil;
+  tmp^.flags := 0;
+
+  If source^.indexed Then
+    { For 8 bit indexed, just look at the destination bit depth and check
+      if the converter's processor is a subset of our processor }
+    For i := 0 To Factory_NumConverters - 1 Do
+      If (Factory_Converters[i].d_bits = dest^.bits) And
+        (Factory_Converters[i].s_idx And
+        ((processor And Factory_Converters[i].processor) <> 0)) Then
+      Begin
+        { If any routines are unassigned, assign them now }
+
+        If tmp^.loopnormal = Nil Then
+        Begin
+          tmp^.loopnormal := Factory_Converters[i].loopnormal;
+          found := True;
+        End;
+
+        If tmp^.normal = Nil Then
+        Begin
+          tmp^.normal := Factory_Converters[i].normal;
+          found := True;
+        End;
+
+        If tmp^.loopstretch = Nil Then
+        Begin
+          tmp^.loopstretch := Factory_Converters[i].loopstretch;
+          found := True;
+        End;
+
+        If tmp^.stretch = Nil Then
+        Begin
+          tmp^.stretch := Factory_Converters[i].stretch;
+          found := True;
+        End;
+      End Else
+  Else
+    { Otherwise we need to compare everything, including bitmasks }
+    For i := 0 To Factory_NumConverters - 1 Do
+      If (Factory_Converters[i].d_bits = dest^.bits) And
+         (Factory_Converters[i].d_r = dest^.r) And
+         (Factory_Converters[i].d_g = dest^.g) And
+         (Factory_Converters[i].d_b = dest^.b) And
+         (Factory_Converters[i].d_a = dest^.a) And
+         (Factory_Converters[i].d_idx = dest^.indexed) And
+         (Factory_Converters[i].s_bits = source^.bits) And
+         (Factory_Converters[i].s_r = source^.r) And
+         (Factory_Converters[i].s_g = source^.g) And
+         (Factory_Converters[i].s_b = source^.b) And
+         (Factory_Converters[i].s_a = source^.a) And
+         (Factory_Converters[i].s_idx = source^.indexed) And
+         ((processor And Factory_Converters[i].processor) <> 0) Then
+      Begin
+        { If any routines are unassigned, assign them now }
+
+        If (tmp^.loopnormal = Nil) And
+           (Factory_Converters[i].loopnormal <> Nil) Then
+        Begin
+          tmp^.loopnormal := Factory_Converters[i].loopnormal;
+          found := True;
+        End;
+
+        If (tmp^.normal = Nil) And
+           (Factory_Converters[i].normal <> Nil) Then
+        Begin
+          tmp^.normal := Factory_Converters[i].normal;
+          found := True;
+        End;
+
+        If (tmp^.loopstretch = Nil) And
+           (Factory_Converters[i].loopstretch <> Nil) Then
+        Begin
+          tmp^.loopstretch := Factory_Converters[i].loopstretch;
+          found := True;
+        End;
+
+        If (tmp^.stretch = Nil) And
+           (Factory_Converters[i].stretch <> Nil) Then
+        Begin
+          tmp^.stretch := Factory_Converters[i].stretch;
+          found := True;
+        End;
+
+        If (tmp^.dither = Nil) And
+           (Factory_Converters[i].dither <> Nil) Then
+        Begin
+          tmp^.dither := Factory_Converters[i].dither;
+          found := True;
+        End;
+
+        If (tmp^.ditherstretch = Nil) And
+           (Factory_Converters[i].ditherstretch <> Nil) Then
+        Begin
+          tmp^.ditherstretch := Factory_Converters[i].ditherstretch;
+          found := True;
+        End;
+
+        { In the rare event of having everything assigned, pull the emergency
+          break. Otherwise we need to continue looking (might be stretching
+          routines somewhere :)
+          Do I sound like a stewardess? }
+        If (tmp^.loopnormal <> Nil) And (tmp^.normal <> Nil) And
+           (tmp^.loopstretch <> Nil) And (tmp^.stretch <> Nil) And
+           (tmp^.dither <> Nil) And (tmp^.ditherstretch <> Nil) Then
+          Break;
+      End;
+
+  If found Then
+  Begin
+    Hermes_FormatCopy(source, @tmp^.source);
+    Hermes_FormatCopy(dest, @tmp^.dest);
+
+    Hermes_Factory_getConverter := tmp;
+  End
+  Else
+  Begin
+    free(tmp);
+    Hermes_Factory_getConverter := Nil;
+  End;
+End;
+
+Function Hermes_Factory_getEqualConverter(bits : Integer) : PHermesConverter;
+
+Var
+  found : Boolean;
+  tmp : PHermesConverter;
+  asm_found : Integer;
+  c_found : Integer;
+
+Begin
+  found := False;
+  tmp := malloc(SizeOf(THermesConverter));
+  If tmp = Nil Then
+  Begin
+    Hermes_Factory_getEqualConverter := Nil;
+    Exit;
+  End;
+
+  { Set all conversion routines to null }
+  tmp^.loopnormal := Nil;
+  tmp^.loopstretch := Nil;
+  tmp^.normal := Nil;
+  tmp^.stretch := Nil;
+  tmp^.dither := Nil;
+  tmp^.ditherstretch := Nil;
+
+{$IFDEF I386_ASSEMBLER}
+
+  { Try MMX routines }
+  If (tmp^.loopnormal = Nil) Or (tmp^.normal = Nil) Or
+     (tmp^.loopstretch = Nil) Or (tmp^.stretch = Nil) Then
+    If (processor And PROC_MMX_PENTIUM) <> 0 Then
+{      Case bits Of
+      End};
+
+  { Try X86 routines }
+  If (tmp^.loopnormal = Nil) Or (tmp^.normal = Nil) Or
+     (tmp^.loopstretch = Nil) Or (tmp^.stretch = Nil) Then
+    If (processor And PROC_X86_PENTIUM) <> 0 Then
+    Begin
+      asm_found := 0;
+      Case bits Of
+        32 : Begin
+          tmp^.normal := @CopyX86p_4byte; asm_found := 1;
+        End;
+        24 : ;
+        16 : Begin
+          tmp^.normal := @CopyX86p_2byte; asm_found := 1;
+        End;
+         8 : Begin
+          tmp^.normal := @CopyX86p_1byte; asm_found := 1;
+        End;
+      End;
+
+      If (asm_found And 1) <> 0 Then
+      Begin
+        tmp^.loopnormal := @ConvertX86;
+        found := True;
+      End;
+    End;
+
+{$ENDIF I386_ASSEMBLER}
+
+
+  If (tmp^.loopnormal = Nil) Or (tmp^.normal = Nil) Or
+     (tmp^.loopstretch = Nil) Or (tmp^.stretch = Nil) Then
+  Begin
+    c_found := 0;
+
+    Case bits Of
+      32 : Begin
+        If tmp^.normal = Nil Then
+        Begin
+          tmp^.normal := @CopyP_4byte; c_found := c_found Or 1;
+        End;
+        If tmp^.stretch = Nil Then
+        Begin
+          tmp^.stretch := @CopyP_4byte_S; c_found := c_found Or 2;
+        End;
+      End;
+      24 : Begin
+        If tmp^.normal = Nil Then
+        Begin
+          tmp^.normal := @CopyP_3byte; c_found := c_found Or 1;
+        End;
+        If tmp^.stretch = Nil Then
+        Begin
+          tmp^.stretch := @CopyP_3byte_S; c_found := c_found Or 2;
+        End;
+      End;
+      16 : Begin
+        If tmp^.normal = Nil Then
+        Begin
+          tmp^.normal := @CopyP_2byte; c_found := c_found Or 1;
+        End;
+        If tmp^.stretch = Nil Then
+        Begin
+          tmp^.stretch := @CopyP_2byte_S; c_found := c_found Or 2;
+        End;
+      End;
+       8 : Begin
+        If tmp^.normal = Nil Then
+        Begin
+          tmp^.normal := @CopyP_1byte; c_found := c_found Or 1;
+        End;
+        If tmp^.stretch = Nil Then
+        Begin
+          tmp^.stretch := @CopyP_1byte_S; c_found := c_found Or 2;
+        End;
+      End;
+    End;
+
+    If (c_found And 1) <> 0 Then
+    Begin
+      tmp^.loopnormal := @ConvertP; found := True;
+    End;
+    If (c_found And 2) <> 0 Then
+    Begin
+      tmp^.loopstretch := @ConvertPStretch; found := True;
+    End;
+  End;
+
+  If found Then
+    Hermes_Factory_getEqualConverter := tmp
+  Else
+  Begin
+    free(tmp);
+    Hermes_Factory_getEqualConverter := Nil;
+  End;
+End;

+ 138 - 0
packages/hermes/src/format.inc

@@ -0,0 +1,138 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+{Function Hermes_FormatNewEmpty : PHermesFormat;
+Function Hermes_FormatNew(bits : Integer; r, g, b, a : int32;
+                          indexed : Boolean) : PHermesFormat;
+Procedure Hermes_FormatFree(fmt : PHermesFormat);
+Function Hermes_FormatNewEx(bits : Integer; r, g, b, a : int32;
+                            indexed, has_colorkey : Boolean;
+                            colorkey : int32) : PHermesFormat;
+Function Hermes_FormatEquals(op1, op2 : PHermesFormat) : Boolean;
+Procedure Hermes_FormatCopy(source, dest : PHermesFormat);}
+
+Function Hermes_FormatNewEmpty : PHermesFormat;
+
+Var
+  tmp : PHermesFormat;
+
+Begin
+  tmp := malloc(SizeOf(THermesFormat));
+  If tmp = Nil Then
+  Begin
+    Hermes_FormatNewEmpty := Nil;
+    Exit;
+  End;
+  tmp^.bits := 0;
+  tmp^.indexed := False;
+  tmp^.r := 0;
+  tmp^.g := 0;
+  tmp^.b := 0;
+  tmp^.a := 0;
+  tmp^.has_colorkey := False;
+  tmp^.colorkey := 0;
+  Hermes_FormatNewEmpty := tmp;
+End;
+
+Function Hermes_FormatNew(bits : Integer; r, g, b, a : int32;
+                          indexed : Boolean) : PHermesFormat;
+
+Var
+  tmp : PHermesFormat;
+
+Begin
+  If indexed And (bits <> 8) Then
+  Begin
+    Hermes_FormatNew := Nil;
+    Exit;
+  End;
+  tmp := malloc(SizeOf(THermesFormat));
+  If tmp = Nil Then
+  Begin
+    Hermes_FormatNew := Nil;
+    Exit;
+  End;
+  tmp^.bits := bits;
+  tmp^.r := r;
+  tmp^.g := g;
+  tmp^.b := b;
+  tmp^.a := a;
+  tmp^.indexed := indexed;
+  tmp^.has_colorkey := False;
+  tmp^.colorkey := 0;
+  Hermes_FormatNew := tmp;
+End;
+
+Procedure Hermes_FormatFree(fmt : PHermesFormat);
+
+Begin
+  If fmt <> Nil Then
+    free(fmt);
+End;
+
+Function Hermes_FormatNewEx(bits : Integer; r, g, b, a : int32;
+                            indexed, has_colorkey : Boolean;
+                            colorkey : int32) : PHermesFormat;
+
+Var
+  tmp : PHermesFormat;
+
+Begin
+  If indexed And (bits <> 8) Then
+  Begin
+    Hermes_FormatNewEx := Nil;
+    Exit;
+  End;
+  tmp := malloc(SizeOf(THermesFormat));
+  If tmp = Nil Then
+  Begin
+    Hermes_FormatNewEx := Nil;
+    Exit;
+  End;
+  tmp^.bits := bits;
+  tmp^.r := r;
+  tmp^.g := g;
+  tmp^.b := b;
+  tmp^.a := a;
+  tmp^.indexed := indexed;
+  tmp^.has_colorkey := has_colorkey;
+  tmp^.colorkey := colorkey;
+  Hermes_FormatNewEx := tmp;
+End;
+
+Function Hermes_FormatEquals(op1, op2 : PHermesFormat) : Boolean;
+
+Begin
+  Hermes_FormatEquals := ((op1^.indexed = op2^.indexed) And
+                          (op1^.bits = op2^.bits) And
+                          (op1^.r = op2^.r) And
+                          (op1^.g = op2^.g) And
+                          (op1^.b = op2^.b) And
+                          (op1^.a = op2^.a) And
+                          (op1^.has_colorkey = op2^.has_colorkey) And
+                          ((op1^.has_colorkey = False) Or
+                           (op1^.colorkey = op2^.colorkey)));
+End;
+
+Procedure Hermes_FormatCopy(source, dest : PHermesFormat);
+
+Begin
+  Move(source^, dest^, SizeOf(THermesFormat));
+End;

+ 42 - 0
packages/hermes/src/headp.inc

@@ -0,0 +1,42 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+{ This little definition makes everything much nicer below here }
+{$MACRO ON}
+{$define CONVERT_PARAMETERS:=source, dest : Pchar8; count, inc_source : DWord}
+
+{$I p_16.inc}
+{$I p_24.inc}
+{$I p_32.inc}
+{ $I p32aoblt.pp}
+{$I p_clr.inc}
+{$I p_cnv.inc}
+{$I p_cpy.inc}
+{$I p_g.inc}
+{$I p_ga.inc}
+{$I p_gac.inc}
+{ $I p_gaoblt.pp}
+{$I p_gca.inc}
+{$I p_gcc.inc}
+{ $I p_gccblt.pp}
+{ $I p_gcoblt.pp}
+{$I p_i8.inc}
+{$I p_muhmu.inc}
+{$I d_32.inc}

+ 40 - 0
packages/hermes/src/hermconf.inc

@@ -0,0 +1,40 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+
+Const
+  HERMES_INITIAL = 8; { Initial size and growth of dynamic }
+  HERMES_GROWTH = 4; { array structures }
+
+  A_32 = 3;		      { oh yes, hardcode it... tsk tsk tsk }
+  R_32 = 2;                   { Position of R,G,B in a 32 bit dword }
+  G_32 = 1;
+  B_32 = 0;
+  R_24 = 2;                   { Position of R,G,B in a 24 bit pixel }
+  G_24 = 1;
+  B_24 = 0;
+{  #define DWORD_BYTE0(s) s         /* Shift values to get to bytes in dwords */
+  #define DWORD_BYTE1(s) ((s)<<8)  /* Check out the bracket paranoia to */   
+  #define DWORD_BYTE2(s) ((s)<<16) /* prevent bugs :)) */     
+  #define DWORD_BYTE3(s) ((s)<<24)       
+  #define DWORD_SHORT0(s) s
+  #define DWORD_SHORT1(s) ((s)<<16)
+  #define DWORD_SHORT0(s) s
+  #define DWORD_SHORT1(s) ((s)<<16)}

+ 60 - 0
packages/hermes/src/hermdef.inc

@@ -0,0 +1,60 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+
+{$IFDEF CPU86}
+  {$DEFINE I386_ASSEMBLER}
+  {$IFNDEF win32}
+    Const
+      ExternalAsmPrefix='_';
+  {$ELSE win32}
+    Const
+      ExternalAsmPrefix='';
+  {$ENDIF win32}
+{$ENDIF CPU86}
+
+{$IFDEF VER1_0}
+  {$IFDEF ENDIAN_LITTLE}
+    {$DEFINE FPC_LITTLE_ENDIAN}
+  {$ENDIF ENDIAN_LITTLE}
+  {$IFDEF ENDIAN_BIG}
+    {$DEFINE FPC_BIG_ENDIAN}
+  {$ENDIF ENDIAN_BIG}
+  Type
+    PtrInt = LongInt;
+    PtrUInt = Cardinal;
+{$ENDIF VER1_0}
+
+{$IFDEF FPC_LITTLE_ENDIAN}
+  {$IFDEF FPC_BIG_ENDIAN}
+    {$FATAL Both FPC_LITTLE_ENDIAN and FPC_BIG_ENDIAN defined?!}
+  {$ENDIF FPC_BIG_ENDIAN}
+{$ELSE FPC_LITTLE_ENDIAN}
+  {$IFNDEF FPC_BIG_ENDIAN}
+    {$FATAL Neither FPC_LITTLE_ENDIAN, nor FPC_BIG_ENDIAN defined?!}
+  {$ENDIF FPC_BIG_ENDIAN}
+{$ENDIF FPC_LITTLE_ENDIAN}
+
+{$IFDEF FPC_LITTLE_ENDIAN}
+  {$INFO FPC_LITTLE_ENDIAN}
+{$ENDIF FPC_LITTLE_ENDIAN}
+{$IFDEF FPC_BIG_ENDIAN}
+  {$INFO FPC_BIG_ENDIAN}
+{$ENDIF FPC_BIG_ENDIAN}

+ 536 - 0
packages/hermes/src/hermes.pp

@@ -0,0 +1,536 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+Unit Hermes;
+
+{$MODE objfpc}
+
+Interface
+
+Const
+  HERMES_CONVERT_NORMAL = 0;
+  HERMES_CONVERT_DITHER = 1;
+
+Type
+  THermesHandle = Integer;
+  Pint32 = ^int32;
+  int32 = DWord;
+  Pshort16 = ^short16;
+  short16 = Word;
+  Pchar8 = ^char8;
+  char8 = Byte;
+  PHermesFormat = ^THermesFormat;
+  THermesFormat = Record
+    r,g,b,a : int32;
+    bits : Integer;
+    indexed : Boolean;
+    has_colorkey : Boolean;
+    colorkey : int32;
+  End;
+
+Function Hermes_FormatNewEmpty : PHermesFormat;
+
+{ Create a new format structure, returns 0 if failed. }
+Function Hermes_FormatNew(bits : Integer; r, g, b, a : int32;
+                          indexed : Boolean) : PHermesFormat;
+
+{ Free a format structure }
+Procedure Hermes_FormatFree(fmt : PHermesFormat);
+
+{ Create a new format structure with colorkey info, returns 0 if failed. }
+Function Hermes_FormatNewEx(bits : Integer; r, g, b, a : int32;
+                            indexed, has_colorkey : Boolean;
+                            colorkey : int32) : PHermesFormat;
+
+{ Compare two formats. Return true if they are equal, false otherwise }
+Function Hermes_FormatEquals(op1, op2 : PHermesFormat) : Boolean;
+
+{ Copy the contents of format 'source' to format 'destination' }
+Procedure Hermes_FormatCopy(source, dest : PHermesFormat);
+
+
+{
+   Get a converter to work with, specifying a combination of the flags
+   above. Returns 0 if unsuccessful.
+}
+Function Hermes_ConverterInstance(flags : DWord) : THermesHandle;
+
+{
+   Return a converter if it is not needed anymore, thus releasing some
+   memory.
+}
+Procedure Hermes_ConverterReturn(handle : THermesHandle);
+
+{
+   Request a format conversion between two formats. This function returns false
+   if the conversion cannot be provided (which should not occur too often :)
+   Repeated calls to this function will be cached an terminate almost
+   immediately, so don't be ashamed of calling it often.
+}
+Function Hermes_ConverterRequest(handle : THermesHandle;
+                                 source, dest : PHermesFormat) : Boolean;
+
+{
+   Set the palette of the source surface / destination surface for a
+   subsequent conversion. At the moment, only sourcepal is used.
+   Returns false if unsuccessful (invalid handle!).
+}
+Function Hermes_ConverterPalette(handle, sourcepal, destpal : THermesHandle) : Boolean;
+
+{
+   Do a format conversion after calling the setup routines above. This will
+   convert (or copy) the pixel data from s_pixels to the data in d_pixels.
+   Both source and destination areas/origins can be specified as well as
+   the scanline width in bytes of the source/destination.
+   Returns false if unsuccessful (invalid handle or request not called before).
+}
+Function Hermes_ConverterCopy(handle : THermesHandle; s_pixels : Pointer;
+                              s_x, s_y, s_width, s_height, s_pitch : Integer;
+                              d_pixels : Pointer; d_x, d_y, d_width,
+                              d_height, d_pitch : Integer) : Boolean;
+
+(*
+{-----------------H_BLIT---------------}
+
+{
+   Get a blitter to work with, specifying a combination of the flags
+   in H_Conv. Returns 0 if unsuccessful.
+}
+Function Hermes_BlitterInstance(flags : DWord) : THermesHandle;
+
+{
+   Return a blitter if it is not needed anymore, thus releasing some
+   memory.
+}
+Procedure Hermes_BlitterReturn(handle : THermesHandle);
+
+{
+   Request a format blitting between two formats. This function returns false
+   if the blitting cannot be provided (which should not occur too often :)
+   Repeated calls to this function will be cached an terminate almost
+   immediately, so don't be ashamed of calling it often.
+}
+Function Hermes_BlitterRequest(handle : THermesHandle;
+                               source, dest : PHermesFormat) : Boolean;
+
+{
+   Set the palette of the source surface / destination surface for a
+   subsequent blitting. At the moment, only sourcepal is used.
+   Returns false if unsuccessful (invalid handle!).
+}
+Function Hermes_BlitterPalette(handle, sourcepal, destpal : THermesHandle) : Boolean;
+
+{
+   Do a format blitting after calling the setup routines above. This will
+   blit the pixel data from s_pixels to the data in d_pixels.  Both source
+   and destination areas/origins can be specified as well as the scanline
+   width in bytes of the source/destination.  Returns false if unsuccessful
+   (invalid handle or request not called before).
+}
+Function Hermes_BlitterBlit(handle : THermesHandle; s_pixels : Pointer;
+                            s_x, s_y, s_width, s_height, s_pitch : Integer;
+                            d_pixels : Pointer; d_x, d_y, d_width, d_height,
+                            d_pitch : Integer) : Boolean;
+*)
+{-----------------H_PAL---------------}
+
+{ Get a handle for a palette to work with. This allocates memory for an
+   internal palette. Returns 0 if failed.
+}
+Function Hermes_PaletteInstance : THermesHandle;
+
+{
+   Return a handle for a palette if the palette isn't used anymore. The
+   internal palette will be deallocated.
+}
+Procedure Hermes_PaletteReturn(handle : THermesHandle);
+
+{
+   Copy the contents of the palette parameter provided into the internal
+   palette. The user palette has to be 256*4 bytes long.
+}
+Procedure Hermes_PaletteSet(handle : THermesHandle; palette : Pointer);
+
+{
+   Return the pointer to the internal palette. The palette is 256*4 bytes
+   long.
+}
+Function Hermes_PaletteGet(handle : THermesHandle) : Pointer;
+
+{
+   Force invalidation of the palette cache. This will force lookup tables to
+   be regenerated and has to be done manually after PaletteGet has been used
+   and the data has been modified without the knowledge of Hermes.
+}
+Procedure Hermes_PaletteInvalidateCache(handle : THermesHandle);
+
+
+{-----------------H_CLEAR---------------}
+
+{
+   Get a handle for a new clearer instance to work with. Returns 0 if failed.
+}
+Function Hermes_ClearerInstance : THermesHandle;
+
+{
+   Return the clearer instance if it is no longer needed.
+}
+Procedure Hermes_ClearerReturn(handle : THermesHandle);
+
+{
+   Request the clearing routines to be set up for clearing to a specific
+   format later. Repeated calls to the routine will be cached and terminate
+   after a short check.
+}
+Function Hermes_ClearerRequest(handle : THermesHandle; format : PHermesFormat) : Boolean;
+
+{
+   Clear a surface. pixels points to the pixel data, x1, y1, width, height
+   specify the area to clear, pitch is the width of a scanline in bytes,
+   the rest are the colour components.
+}
+Function Hermes_ClearerClear(handle : THermesHandle; pixels : Pointer;
+                             x1, y1, width, height, pitch : Integer;
+                             r, g, b : int32; index : char8) : Boolean;
+
+
+{ Initialise Hermes, returns false if failed }
+Function Hermes_Init : Boolean;
+
+{ Deinitialise Hermes, returns false if failed }
+Function Hermes_Done : Boolean;
+
+Implementation
+
+{$I hermdef.inc}
+
+Const
+  PROC_GENERIC = 1;
+  PROC_X86_PENTIUM = 2;
+  PROC_MMX_PENTIUM = 4;
+  HERMES_CONVERT_GENERIC = 65536;
+
+{$I hermconf.inc}
+
+Type
+  PHermesClearInterface = ^THermesClearInterface;
+  THermesClearInterface = Record
+    dest : ^char8;
+    value : int32;
+    width, height : Integer;
+    add : Integer;
+  End;
+  THermesClearPtr = Procedure(hci : PHermesClearInterface); CDecl;
+  PHermesClearer = ^THermesClearer;
+  THermesClearer = Record
+    bits : Integer;
+    func : THermesClearPtr;
+  End;
+
+
+{ Structure to hold shift amounts for the generic routines }
+  PHermesGenericInfo = ^THermesGenericInfo;
+  THermesGenericInfo = Record
+    r_right, g_right, b_right, a_right : Integer; {Shift amount to the right}
+    r_left, g_left, b_left, a_left : Integer; {Shift amount to the right}
+  End;
+
+
+{ Pointer to specialised (one-scanline-only) conversion procedure }
+  THermesConverterPtr = Procedure(source, dest : Pchar8;
+                                  count, inc_source : DWord); CDecl;
+
+{ Structure for conversion loop routines, don't be scared, size does NOT
+   matter in this case :) }
+  PHermesConverterInterface = ^THermesConverterInterface;
+  THermesConverterInterface = Record
+    s_pixels : Pchar8;
+    s_width,s_height : Integer;
+    s_add : Integer;          { Offset to next line from end of line }
+
+    d_pixels : Pchar8;
+    d_width,d_height : Integer;
+    d_add : Integer;
+
+    func : THermesConverterPtr;
+
+    lookup : Pint32;          { Palette lookup table ptr, for 8 bit }
+
+    s_pitch : Integer;        { Source and destination pitch, }
+    d_pitch : Integer;        { only used by C routines }
+
+    info : THermesGenericInfo; { Only used by generic converters }
+    mask_r, mask_g, mask_b, mask_a : int32; { Only used by generic converters }
+    s_mask_a : int32;
+
+    s_has_colorkey : Boolean;
+    s_colorkey : int32;
+
+    d_has_colorkey : Boolean;
+    d_colorkey : int32;
+  End;
+
+{ Pointer to loop function (C, assembler main loop, generic routines) }
+  THermesConverterLoopPtr = Procedure(hci : PHermesConverterInterface); CDecl;
+
+  PHermesConverter = ^THermesConverter;
+  THermesConverter = Record
+    source,dest : THermesFormat;           { Source and destination format }
+    lookup : Pint32;                       { Pointer to lookup table (8bit) }
+
+    flags : DWord;                         { Defined in H_Conv.h, DITHER,etc}
+
+    loopnormal : THermesConverterLoopPtr;  { Loop routine for normal conv. }
+    loopstretch : THermesConverterLoopPtr;
+    normal : THermesConverterPtr;          { One-scanline routine }
+    stretch : THermesConverterPtr;
+
+    dither : THermesConverterLoopPtr;        { Dithering routines always }
+    ditherstretch : THermesConverterLoopPtr; { convert the whole buffer }
+  End;
+
+  PHermesFactoryStruct = ^THermesFactoryStruct;
+  THermesFactoryStruct = Record
+    s_bits : Integer;
+    s_idx : Boolean;
+    s_r, s_g, s_b, s_a : int32;
+    d_bits : Integer;
+    d_idx : Boolean;
+    d_r, d_g, d_b, d_a : int32;
+
+    loopnormal, loopstretch : THermesConverterLoopPtr;
+    normal, stretch : THermesConverterPtr;
+    dither, ditherstretch : THermesConverterLoopPtr;
+
+    processor : Integer;
+  End;
+
+{dither types ?}
+
+Const
+{ p_converters holds a list of formats, for conversion from 32 bit, 24 bit,
+  16 bit, muhmu and 8 bit.
+  The destination formats are listed in the order of frequency they might
+  occur so common formats can be retrieved faster.
+
+  Format of a row:
+  source bpp, s. indexed, s. r_mask, s. g_mask, s. b_mask, s. alpha ,dest bpp,
+  d.indexed, d. r_mask, d. g_mask, d. b_mask, d. alpha
+}
+{ I wish I could touch this, but it's used in too many other placed in the code,
+  ( at least indirectly), and many of the indicies are hardcoded }
+  p_converters : Array[0..4, 0..11, 0..11] Of DWord =
+  (
+  ( {From 32 bit RGB 888}
+  (32,0,$ff0000,$ff00,$ff,0,16,0,$f800,$7e0,$1f,0),          {16RGB565 }
+  (32,0,$ff0000,$ff00,$ff,0, 8,0,$e0,$1c,$3,0),              { 8RGB332 }
+  (32,0,$ff0000,$ff00,$ff,0,16,0,$7c00,$3e0,$1f,0),          { 16RGB555 }
+  (32,0,$ff0000,$ff00,$ff,0,24,0,$ff0000,$ff00,$ff,0),       { 24RGB888 }
+  (32,0,$ff0000,$ff00,$ff,0,32,0,$ff,$ff00,$ff0000,0),       { 32BGR888 }
+  (32,0,$ff0000,$ff00,$ff,0,16,0,$1f,$7e0,$f800,0),          { 16BGR565 }
+  (32,0,$ff0000,$ff00,$ff,0,16,0,$1f,$3e0,$7c00,0),          { 16BGR555 }
+  (32,0,$ff0000,$ff00,$ff,0,32,0,$ff000000,$ff0000,$ff00,$ff), { 32RGBA888 }
+  (32,0,$ff0000,$ff00,$ff,0,32,0,$ff00,$ff0000,$ff000000,$ff), { 32BGRA888 }
+  (32,0,$ff0000,$ff00,$ff,0,24,0,$ff,$ff00,$ff0000,0),       { 24BGR888 }
+  (0,0,0,0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0,0,0,0)
+  )
+  ,
+  ( {From 24 bit RGB 888}
+  (24,0,$ff0000,$ff00,$ff,0,32,0,$ff0000,$ff00,$ff,0),       { 32RGB888 }
+  (24,0,$ff0000,$ff00,$ff,0,16,0,$f800,$7e0,$1f,0),          { 16RGB565 }
+  (24,0,$ff0000,$ff00,$ff,0, 8,0,$e0,$1c,$3,0),              { 8RGB332 }
+  (24,0,$ff0000,$ff00,$ff,0,16,0,$7c00,$3e0,$1f,0),          { 16RGB555 }
+  (24,0,$ff0000,$ff00,$ff,0,32,0,$ff,$ff00,$ff0000,0),       { 32BGR888 }
+  (24,0,$ff0000,$ff00,$ff,0,16,0,$1f,$7e0,$f800,0),          { 16BGR565 }
+  (24,0,$ff0000,$ff00,$ff,0,16,0,$1f,$3e0,$7c00,0),          { 16BGR555 }
+  (24,0,$ff0000,$ff00,$ff,0,32,0,$ff000000,$ff0000,$ff00,$ff), { 32RGBA888 }
+  (24,0,$ff0000,$ff00,$ff,0,32,0,$ff00,$ff0000,$ff000000,$ff), { 32BGRA888 }
+  (24,0,$ff0000,$ff00,$ff,0,24,0,$ff,$ff00,$ff0000,0),       { 24BGR888 }
+  (0,0,0,0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0,0,0,0)
+  )
+  ,
+  ( {From 16 bit RGB 565}
+  (16,0,$f800,$7e0,$1f,0,32,0,$ff0000,$ff00,$ff,0),          { 32RGB888 }
+  (16,0,$f800,$7e0,$1f,0, 8,0,$e0,$1c,$3,0),                 { 8RGB332 }
+  (16,0,$f800,$7e0,$1f,0,16,0,$7c00,$3e0,$1f,0),             { 16RGB555 }
+  (16,0,$f800,$7e0,$1f,0,24,0,$ff0000,$ff00,$ff,0),          { 24RGB888 }
+  (16,0,$f800,$7e0,$1f,0,32,0,$ff,$ff00,$ff0000,0),          { 32BGR888 }
+  (16,0,$f800,$7e0,$1f,0,16,0,$1f,$7e0,$f800,0),             { 16BGR565 }
+  (16,0,$f800,$7e0,$1f,0,16,0,$1f,$3e0,$7c00,0),             { 16BGR555 }
+  (16,0,$f800,$7e0,$1f,0,32,0,$ff000000,$ff0000,$ff00,$ff),    { 32RGBA888 }
+  (16,0,$f800,$7e0,$1f,0,32,0,$ff00,$ff0000,$ff000000,$ff),    { 32BGRA888 }
+  (16,0,$f800,$7e0,$1f,0,24,0,$ff,$ff00,$ff0000,0),          { 24BGR888 }
+  (0,0,0,0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0,0,0,0)
+  ),
+  ( {From 32 bit muhmu}
+  (32,0,$ff00000,$3fc00,$ff,0,32,0,$ff0000,$ff00,$ff,0),     { 32RGB888 }
+  (32,0,$ff00000,$3fc00,$ff,0,16,0,$f800,$7e0,$1f,0),        { 16RGB565 }
+  (32,0,$ff00000,$3fc00,$ff,0, 8,0,$e0,$1c,$3,0),            { 8RGB332 }
+  (32,0,$ff00000,$3fc00,$ff,0,16,0,$7c00,$3e0,$1f,0),        { 16RGB555 }
+  (32,0,$ff00000,$3fc00,$ff,0,24,0,$ff0000,$ff00,$ff,0),     { 24RGB888 }
+  (32,0,$ff00000,$3fc00,$ff,0,32,0,$ff,$ff00,$ff0000,0),     { 32BGR888 }
+  (32,0,$ff00000,$3fc00,$ff,0,16,0,$1f,$7e0,$f800,0),        { 16BGR565 }
+  (32,0,$ff00000,$3fc00,$ff,0,16,0,$1f,$3e0,$7c00,0),        { 16BGR555 }
+  (32,0,$ff00000,$3fc00,$ff,0,32,0,$ff000000,$ff0000,$ff00,$ff), { 32RGBA888 }
+  (32,0,$ff00000,$3fc00,$ff,0,32,0,$ff00,$ff0000,$ff000000,$ff), { 32BGRA888 }
+  (32,0,$ff00000,$3fc00,$ff,0,24,0,$ff,$ff00,$ff0000,0),     { 24BGR888 }
+  (0,0,0,0,0,0,0,0,0,0,0,0)
+  ),
+  ( {From 8 bit indexed}
+  (8,1,0,0,0,0,32,0,0,0,0,0),
+  (8,1,0,0,0,0,24,0,0,0,0,0),
+  (8,1,0,0,0,0,16,0,0,0,0,0),
+  (8,1,0,0,0,0,8,0,0,0,0,0),
+  (0,0,0,0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0,0,0,0),
+  (0,0,0,0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0,0,0,0),
+  (0,0,0,0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0,0,0,0),
+  (0,0,0,0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0,0,0,0)
+  )
+  );
+  numConverters : Array[0..4] Of Integer = (10,10,10,11,4);
+  refcount : Integer = 0;
+
+Var
+  Clearers : Array[0..3] Of PHermesClearer;
+  numClearers : Integer;
+  standardConverters : Array[0..4] Of ^PHermesConverter;
+  equalConverters : Array[0..3] Of PHermesConverter;
+
+{$I malloc.inc}
+
+{$I debug.inc}
+
+{$I dither.inc}
+{$I headp.inc}
+{$IFDEF I386_ASSEMBLER}
+  {$I i386/headi386.inc}
+  {$I i386/headmmx.inc}
+{$ENDIF I386_ASSEMBLER}
+{$I factconv.inc}
+{$I list.inc}
+{$I utility.inc}
+{$I format.inc}
+{$I palette.inc}
+{$I convert.inc}
+{$I clear.inc}
+{$I factory.inc}
+
+Function Hermes_Init : Boolean;
+
+Var
+  i, j : Integer;
+  source, dest : THermesFormat;
+
+Begin
+  If refcount > 0 Then
+  Begin
+    Inc(refcount);
+    Hermes_Init := True;
+    Exit;
+  End;
+  { Initialise hermes factory }
+  Hermes_Factory_Init;
+
+  { Instruct the factory to return clearing routines }
+  Clearers[0] := Hermes_Factory_getClearer(32);
+  Clearers[1] := Hermes_Factory_getClearer(24);
+  Clearers[2] := Hermes_Factory_getClearer(16);
+  Clearers[3] := Hermes_Factory_getClearer(8);
+  numClearers := 4;
+
+  { Use factory to obtain specialised converters }
+  For j := 0 To 4 Do
+  Begin
+    standardConverters[j] := malloc(SizeOf(PHermesConverter)*numConverters[j]);
+    For i := 0 To numConverters[j] - 1 Do
+    Begin
+      // xxx jm color keys not taken into consideration here
+      FillChar(source, SizeOf(source), 0);
+      FillChar(dest, SizeOf(dest), 0);
+      source.bits := p_converters[j, i, 0];    dest.bits := p_converters[j, i, 6];
+      source.indexed:= p_converters[j,i,1]<>0; dest.indexed:= p_converters[j,i,7]<>0;
+      source.r := p_converters[j, i, 2];       dest.r := p_converters[j, i, 8];
+      source.g := p_converters[j, i, 3];       dest.g := p_converters[j, i, 9];
+      source.b := p_converters[j, i, 4];       dest.b := p_converters[j, i, 10];
+      source.a := p_converters[j, i, 5];       dest.a := p_converters[j, i, 11];
+
+      standardConverters[j][i] := Hermes_Factory_getConverter(@source, @dest);
+    End;
+  End;
+
+
+  { Set up converters for equal colour formats }
+  equalConverters[3] := Hermes_Factory_getEqualConverter(32);
+  equalConverters[2] := Hermes_Factory_getEqualConverter(24);
+  equalConverters[1] := Hermes_Factory_getEqualConverter(16);
+  equalConverters[0] := Hermes_Factory_getEqualConverter(8);
+
+  { Initialise dithering tables }
+  Dither_SetupMatrices;
+
+  Inc(refcount);
+  Hermes_Init := True;
+End;
+
+Function Hermes_Done : Boolean;
+
+Var
+  i, j : Integer;
+
+Begin
+  Dec(refcount);
+  If refcount < 0 Then
+  Begin
+    refcount := 0;
+    Hermes_Done := False;
+    Exit;
+  End;
+  If refcount = 0 Then
+  Begin
+    For i := 0 To 3 Do
+    Begin
+      If Clearers[i] <> Nil Then
+      Begin
+        free(Clearers[i]);
+        Clearers[i] := Nil;
+      End;
+      If equalConverters[i] <> Nil Then
+      Begin
+        free(equalConverters[i]);
+        equalConverters[i] := Nil;
+      End;
+    End;
+    For i := 0 To 4 Do
+    Begin
+      If standardConverters[i] <> Nil Then
+      Begin
+        For j := 0 To numConverters[i] - 1 Do
+          free(standardConverters[i][j]);
+        free(standardConverters[i]);
+      End;
+      standardConverters[i] := Nil;
+    End;
+  End;
+  Hermes_Done := True;
+End;
+
+Begin
+  DebugInit;
+End.

+ 44 - 0
packages/hermes/src/i386/headi386.inc

@@ -0,0 +1,44 @@
+
+{$L hm_i386}
+
+Procedure ConvertX86(hci : PHermesConverterInterface); CDecl; External name ExternalAsmPrefix+'ConvertX86';
+Procedure ConvertX86Stretch(hci : PHermesConverterInterface); CDecl; External name ExternalAsmPrefix+'ConvertX86Stretch';
+Procedure ClearX86_32(hci : PHermesClearInterface); CDecl; External name ExternalAsmPrefix+'ClearX86_32';
+Procedure ClearX86_24(hci : PHermesClearInterface); CDecl; External name ExternalAsmPrefix+'ClearX86_24';
+Procedure ClearX86_16(hci : PHermesClearInterface); CDecl; External name ExternalAsmPrefix+'ClearX86_16';
+Procedure ClearX86_8(hci : PHermesClearInterface); CDecl; External name ExternalAsmPrefix+'ClearX86_8';
+
+Function Hermes_X86_CPU : Integer; CDecl; External name ExternalAsmPrefix+'Hermes_X86_CPU';
+
+Procedure ConvertX86p32_32BGR888(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertX86p32_32BGR888';
+Procedure ConvertX86p32_32RGBA888(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertX86p32_32RGBA888';
+Procedure ConvertX86p32_32BGRA888(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertX86p32_32BGRA888';
+Procedure ConvertX86p32_24RGB888(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertX86p32_24RGB888';
+Procedure ConvertX86p32_24BGR888(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertX86p32_24BGR888';
+Procedure ConvertX86p32_16RGB565(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertX86p32_16RGB565';
+Procedure ConvertX86p32_16BGR565(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertX86p32_16BGR565';
+Procedure ConvertX86p32_16RGB555(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertX86p32_16RGB555';
+Procedure ConvertX86p32_16BGR555(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertX86p32_16BGR555';
+Procedure ConvertX86p32_8RGB332(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertX86p32_8RGB332';
+
+Procedure ConvertX86p32_16RGB565_S(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertX86p32_16RGB565_S';
+
+Procedure ConvertX86p16_32RGB888(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertX86p16_32RGB888';
+Procedure ConvertX86p16_32BGR888(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertX86p16_32BGR888';
+Procedure ConvertX86p16_32RGBA888(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertX86p16_32RGBA888';
+Procedure ConvertX86p16_32BGRA888(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertX86p16_32BGRA888';
+Procedure ConvertX86p16_24RGB888(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertX86p16_24RGB888';
+Procedure ConvertX86p16_24BGR888(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertX86p16_24BGR888';
+Procedure ConvertX86p16_16BGR565(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertX86p16_16BGR565';
+Procedure ConvertX86p16_16RGB555(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertX86p16_16RGB555';
+Procedure ConvertX86p16_16BGR555(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertX86p16_16BGR555';
+Procedure ConvertX86p16_8RGB332(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertX86p16_8RGB332';
+
+Procedure CopyX86p_4byte(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'CopyX86p_4byte';
+Procedure CopyX86p_3byte(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'CopyX86p_3byte';
+Procedure CopyX86p_2byte(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'CopyX86p_2byte';
+Procedure CopyX86p_1byte(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'CopyX86p_1byte';
+
+Procedure ConvertX86pI8_32(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertX86pI8_32';
+Procedure ConvertX86pI8_24(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertX86pI8_24';
+Procedure ConvertX86pI8_16(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertX86pI8_16';

+ 20 - 0
packages/hermes/src/i386/headmmx.inc

@@ -0,0 +1,20 @@
+
+{$L mmx_clr}
+{$L mmx_main}
+{$L mmxp2_32}
+{$L mmxp_32}
+
+Procedure ConvertMMX(hci : PHermesConverterInterface); CDecl; External name ExternalAsmPrefix+'ConvertMMX';
+
+Procedure ClearMMX_32(hci : PHermesClearInterface); CDecl; External name ExternalAsmPrefix+'ClearMMX_32';
+Procedure ClearMMX_24(hci : PHermesClearInterface); CDecl; External name ExternalAsmPrefix+'ClearMMX_24';
+Procedure ClearMMX_16(hci : PHermesClearInterface); CDecl; External name ExternalAsmPrefix+'ClearMMX_16';
+Procedure ClearMMX_8(hci : PHermesClearInterface); CDecl; External name ExternalAsmPrefix+'ClearMMX_8';
+
+Procedure ConvertMMXpII32_24RGB888(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertMMXpII32_24RGB888';
+Procedure ConvertMMXpII32_16RGB565(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertMMXpII32_16RGB565';
+Procedure ConvertMMXpII32_16BGR565(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertMMXpII32_16BGR565';
+Procedure ConvertMMXpII32_16RGB555(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertMMXpII32_16RGB555';
+Procedure ConvertMMXpII32_16BGR555(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertMMXpII32_16BGR555';
+
+Procedure ConvertMMXp32_16RGB555(CONVERT_PARAMETERS); CDecl; External name ExternalAsmPrefix+'ConvertMMXp32_16RGB555';

+ 271 - 0
packages/hermes/src/i386/mmx_clr.as

@@ -0,0 +1,271 @@
+#
+# MMX surface clear routines for HERMES
+# Copyright (c) 1998 Christian Nentwich ([email protected])
+# This source code is licensed under the GNU LGPL
+# 
+# Please refer to the file COPYING.LIB contained in the distribution for
+# licensing conditions
+#
+
+
+.globl _ClearMMX_32
+.globl _ClearMMX_24
+.globl _ClearMMX_16
+.globl _ClearMMX_8
+
+.text
+
+##
+## --------------------------------------------------------------------------
+## HermesClearInterface (ebp+..)
+##   0: char8 *dest
+##   4: int32 value
+##   8: unsigned int width (already checked to be >0!)
+##  12: unsigned int height (already checked to be >0!)
+##  16: int add
+
+
+_ClearMMX_32: 
+        pushl %ebp
+        movl %esp,%ebp
+
+        movl 8(%ebp),%ebp
+
+        movl 4(%ebp),%eax       # pixel value   
+        movd 4(%ebp),%mm0
+
+        movl 12(%ebp),%edx      # height
+        movq %mm0,%mm1
+
+        psllq $32,%mm0
+        movl (%ebp),%edi        # destination
+
+        por %mm1,%mm0
+_ClearMMX_32.L_y: 
+        movl 8(%ebp),%ecx
+
+        movl %ecx,%ebx
+
+        shrl %ecx
+        jz _ClearMMX_32.L_last
+
+_ClearMMX_32.L_x: 
+        movq %mm0,(%edi)
+        addl $8,%edi
+
+        decl %ecx
+        jnz _ClearMMX_32.L_x
+
+
+_ClearMMX_32.L_last: 
+        testl $1,%ebx
+        jz _ClearMMX_32.L_endline
+
+        movl %eax,(%edi)
+        addl $4,%edi
+
+_ClearMMX_32.L_endline: 
+
+        addl 16(%ebp),%edi
+
+        decl %edx
+        jnz _ClearMMX_32.L_y
+
+        emms
+
+        popl %ebp
+        ret
+
+
+
+_ClearMMX_24: 
+        ret
+
+
+
+_ClearMMX_16: 
+        pushl %ebp
+        movl %esp,%ebp
+
+        movl 8(%ebp),%ebp
+
+        movl 4(%ebp),%eax       # pixel value   
+        movl 4(%ebp),%ebx
+
+        movl 12(%ebp),%edx      # height
+        movl (%ebp),%edi        # destination
+
+        shll $16,%eax           # Duplicate pixel value
+        andl $0x0ffff,%ebx
+
+        orl %ebx,%eax
+
+        movd %eax,%mm0
+        movd %eax,%mm1
+
+        psllq $32,%mm0
+
+        por %mm1,%mm0
+_ClearMMX_16.L_y: 
+        movl 8(%ebp),%ecx
+
+        testl $3,%edi           # Check if destination is aligned mod 4
+        jz _ClearMMX_16.L_aligned
+
+        movw %ax,(%edi)         # otherwise write one pixel
+        addl $2,%edi
+
+        decl %ecx
+        jz _ClearMMX_16.L_endline
+
+_ClearMMX_16.L_aligned: 
+        movl %ecx,%ebx
+        shrl $2,%ecx
+
+        jz _ClearMMX_16.L_last
+
+_ClearMMX_16.L_x: 
+        movq %mm0,(%edi)
+        addl $8,%edi
+
+        decl %ecx
+        jnz _ClearMMX_16.L_x
+
+_ClearMMX_16.L_last: 
+        andl $3,%ebx
+        jz _ClearMMX_16.L_endline
+
+        movw %ax,(%edi)         # Write trailing pixels
+        addl $2,%edi
+        decl %ebx
+        jz _ClearMMX_16.L_endline
+
+        movw %ax,(%edi)
+        addl $2,%edi
+        decl %ebx
+        jz _ClearMMX_16.L_endline
+
+        movw %ax,(%edi)
+        addl $2,%edi
+        decl %ebx
+        jnz _ClearMMX_16.L_endline
+
+_ClearMMX_16.L_endline: 
+        addl 16(%ebp),%edi
+
+        decl %edx
+        jnz _ClearMMX_16.L_y
+
+        emms
+
+        popl %ebp
+        ret
+
+
+
+## Clear8_x86 isnt optimised fully yet as it seems to be a tiny bit slower
+## than the C routine
+_ClearMMX_8: 
+        pushl %ebp
+        movl %esp,%ebp
+
+        movl 8(%ebp),%ebp
+
+        movl 4(%ebp),%eax       # pixel value           
+        movl 4(%ebp),%ebx
+
+        movl 12(%ebp),%edx      # height
+        andl $0x0ff,%ebx
+
+        shll $8,%eax            # Put the byte pixel value in all four bytes
+        movl (%ebp),%edi        # destination
+
+        movb %bl,%al
+        movb %bl,%bh
+
+        shll $16,%eax
+
+        movb %bh,%ah
+        movb %bl,%al
+
+        movd %eax,%mm0
+        movd %eax,%mm1
+
+        psllq $32,%mm0
+
+        por %mm1,%mm0
+
+_ClearMMX_8.L_y: 
+        movl 8(%ebp),%ecx
+
+        testl $3,%edi           # Align mod 4
+        jz _ClearMMX_8.L_aligned
+
+        movl %edi,%ebx
+
+        andl $3,%ebx
+
+        movb %al,(%edi)         # Unrolled (copy & paste), align and jump
+        incl %edi               # if finished, faster than a loop...
+        decl %ecx
+        jz _ClearMMX_8.L_endline
+        decl %ebx
+        jz _ClearMMX_8.L_aligned
+
+        movb %al,(%edi)         # Second pixel
+        incl %edi
+        decl %ecx
+        jz _ClearMMX_8.L_endline
+        decl %ebx
+        jz _ClearMMX_8.L_aligned
+
+        movb %al,(%edi)         # Third pixel
+        incl %edi
+        decl %ecx
+        jz _ClearMMX_8.L_endline
+        decl %ebx
+        jz _ClearMMX_8.L_aligned
+
+_ClearMMX_8.L_aligned: 
+        movl %ecx,%ebx          # Store ecx for later
+
+        shrl $3,%ecx            # We write 8 pixels at once
+        jz _ClearMMX_8.L_last
+
+_ClearMMX_8.L_x: 
+        movq %mm0,(%edi)
+        addl $8,%edi
+
+        decl %ecx
+        jnz _ClearMMX_8.L_x
+
+_ClearMMX_8.L_last: 
+        movl %ebx,%ecx          # Clean up trailing pixels
+
+        andl $7,%ecx            # Could be up to 7 left
+        jz _ClearMMX_8.L_endline
+
+        testb $0b100,%cl        # If theres less than four jump
+        jz _ClearMMX_8.L_lessthanfour
+
+        movl %eax,(%edi)        # Otherwise write a dword
+        addl $4,%edi
+
+        subl $4,%ecx
+
+_ClearMMX_8.L_lessthanfour: 
+        rep
+ stosb              # Clean up the very rest
+
+_ClearMMX_8.L_endline: 
+        addl 16(%ebp),%edi
+
+        decl %edx
+        jnz _ClearMMX_8.L_y
+
+        emms
+
+        popl %ebp
+        ret
+
+

+ 70 - 0
packages/hermes/src/i386/mmx_main.as

@@ -0,0 +1,70 @@
+#
+# x86 format converters for HERMES
+# Some routines Copyright (c) 1998 Christian Nentwich ([email protected])
+# This source code is licensed under the GNU LGPL
+# 
+# Please refer to the file COPYING.LIB contained in the distribution for
+# licensing conditions          
+#
+# Most routines are (c) Glenn Fiedler ([email protected]), used with permission
+# 
+
+#BITS 32
+
+.globl _ConvertMMX
+.globl _mmxreturn
+
+
+.text
+
+## _ConvertMMX:  
+## [ESP+8] ConverterInfo*
+## --------------------------------------------------------------------------
+## ConverterInfo (ebp+..)
+##   0: void *s_pixels
+##   4: int s_width
+##   8: int s_height
+##  12: int s_add
+##  16: void *d_pixels
+##  20: int d_width
+##  24: int d_height
+##  28: int d_add
+##  32: void (*converter_function)() 
+##  36: int32 *lookup
+
+_ConvertMMX: 
+        pushl %ebp
+        movl %esp,%ebp
+
+        movl 8(%ebp),%eax
+
+        cmpl $0,4(%eax)
+        je endconvert
+
+        movl %eax,%ebp
+
+        movl (%ebp),%esi
+        movl 16(%ebp),%edi
+
+y_loop: 
+        movl 4(%ebp),%ecx
+
+        jmp *32(%ebp)
+
+_mmxreturn: 
+        addl 12(%ebp),%esi
+        addl 28(%ebp),%edi
+
+        decl 8(%ebp)
+        jnz y_loop
+
+
+        popl %ebp
+
+endconvert: 
+        emms
+
+        ret
+
+
+

+ 386 - 0
packages/hermes/src/i386/mmxp2_32.as

@@ -0,0 +1,386 @@
+#
+# pII-optimised MMX format converters for HERMES
+# Copyright (c) 1998 Christian Nentwich ([email protected])
+#   and (c) 1999 Jonathan Matthew ([email protected])
+# This source code is licensed under the GNU LGPL
+# 
+# Please refer to the file COPYING.LIB contained in the distribution for
+# licensing conditions          
+#
+# COPYRIGHT NOTICE
+# 
+# This file partly contains code that is (c) Intel Corporation, specifically
+# the mode detection routine, and the converter to 15 bit (8 pixel
+# conversion routine from the mmx programming tutorial pages).
+#
+#
+# These routines aren't exactly pII optimised - it's just that as they
+# are, theyre terrible on p5 MMXs, but less so on pIIs.  Someone needs to
+# optimise them for p5 MMXs..
+
+#BITS 32
+
+
+.globl _ConvertMMXpII32_24RGB888
+.globl _ConvertMMXpII32_16RGB565
+.globl _ConvertMMXpII32_16BGR565
+.globl _ConvertMMXpII32_16RGB555
+.globl _ConvertMMXpII32_16BGR555
+
+.extern _mmxreturn
+
+.data
+
+.align 8
+
+## Constants for conversion routines
+
+mmx32_rgb888_mask: .long 0x00ffffff,0x00ffffff
+
+mmx32_rgb565_b: .long 0x000000f8,0x000000f8
+mmx32_rgb565_g: .long 0x0000fc00,0x0000fc00
+mmx32_rgb565_r: .long 0x00f80000,0x00f80000
+
+mmx32_rgb555_rb: .long 0x00f800f8,0x00f800f8
+mmx32_rgb555_g: .long 0x0000f800,0x0000f800
+mmx32_rgb555_mul: .long 0x20000008,0x20000008
+mmx32_bgr555_mul: .long 0x00082000,0x00082000
+
+
+
+.text
+
+_ConvertMMXpII32_24RGB888: 
+
+        # set up mm6 as the mask, mm7 as zero
+        movq mmx32_rgb888_mask,%mm6
+        pxor %mm7,%mm7
+
+        movl %ecx,%edx                  # save ecx
+        andl $0x0fffffffc,%ecx          # clear lower two bits
+        jnz _ConvertMMXpII32_24RGB888.L1
+        jmp _ConvertMMXpII32_24RGB888.L2
+
+_ConvertMMXpII32_24RGB888.L1: 
+
+        movq (%esi),%mm0                # A R G B a r g b
+        pand %mm6,%mm0                  # 0 R G B 0 r g b
+        movq 8(%esi),%mm1               # A R G B a r g b
+        pand %mm6,%mm1                  # 0 R G B 0 r g b
+
+        movq %mm0,%mm2                  # 0 R G B 0 r g b
+        punpckhdq %mm7,%mm2             # 0 0 0 0 0 R G B
+        punpckldq %mm7,%mm0             # 0 0 0 0 0 r g b
+        psllq $24,%mm2                  # 0 0 R G B 0 0 0
+        por %mm2,%mm0                   # 0 0 R G B r g b
+
+        movq %mm1,%mm3                  # 0 R G B 0 r g b
+        psllq $48,%mm3                  # g b 0 0 0 0 0 0
+        por %mm3,%mm0                   # g b R G B r g b
+
+        movq %mm1,%mm4                  # 0 R G B 0 r g b
+        punpckhdq %mm7,%mm4             # 0 0 0 0 0 R G B
+        punpckldq %mm7,%mm1             # 0 0 0 0 0 r g b
+        psrlq $16,%mm1                  # 0 0 0 R G B 0 r
+        psllq $8,%mm4                   # 0 0 0 0 R G B 0
+        por %mm4,%mm1                   # 0 0 0 0 R G B r
+
+        movq %mm0,(%edi)
+        addl $16,%esi
+        movd %mm1,8(%edi)
+        addl $12,%edi
+        subl $4,%ecx
+        jnz _ConvertMMXpII32_24RGB888.L1
+
+_ConvertMMXpII32_24RGB888.L2: 
+        movl %edx,%ecx
+        andl $3,%ecx
+        jz _ConvertMMXpII32_24RGB888.L4
+_ConvertMMXpII32_24RGB888.L3: 
+        movb (%esi),%al
+        movb 1(%esi),%bl
+        movb 2(%esi),%dl
+        movb %al,(%edi)
+        movb %bl,1(%edi)
+        movb %dl,2(%edi)
+        addl $4,%esi
+        addl $3,%edi
+        decl %ecx
+        jnz _ConvertMMXpII32_24RGB888.L3
+_ConvertMMXpII32_24RGB888.L4: 
+        jmp _mmxreturn
+
+
+
+_ConvertMMXpII32_16RGB565: 
+
+        # set up masks
+        movq mmx32_rgb565_b,%mm5
+        movq mmx32_rgb565_g,%mm6
+        movq mmx32_rgb565_r,%mm7
+
+        movl %ecx,%edx
+        shrl $2,%ecx
+        jnz _ConvertMMXpII32_16RGB565.L1
+        jmp _ConvertMMXpII32_16RGB565.L2 # not necessary at the moment, but doesnt hurt (much)
+
+_ConvertMMXpII32_16RGB565.L1: 
+        movq (%esi),%mm0        # argb
+        movq %mm0,%mm1          # argb
+        pand %mm6,%mm0          # 00g0
+        movq %mm1,%mm3          # argb
+        pand %mm5,%mm1          # 000b
+        pand %mm7,%mm3          # 0r00
+        pslld $2,%mm1           # 0 0 000000bb bbb00000
+        por %mm1,%mm0           # 0 0 ggggggbb bbb00000
+        psrld $5,%mm0           # 0 0 00000ggg gggbbbbb
+
+        movq 8(%esi),%mm4       # argb
+        movq %mm4,%mm2          # argb
+        pand %mm6,%mm4          # 00g0
+        movq %mm2,%mm1          # argb
+        pand %mm5,%mm2          # 000b
+        pand %mm7,%mm1          # 0r00
+        pslld $2,%mm2           # 0 0 000000bb bbb00000
+        por %mm2,%mm4           # 0 0 ggggggbb bbb00000
+        psrld $5,%mm4           # 0 0 00000ggg gggbbbbb
+
+        packuswb %mm1,%mm3      # R 0 r 0
+        packssdw %mm4,%mm0      # as above.. ish
+        por %mm3,%mm0           # done.
+        movq %mm0,(%edi)
+
+        addl $16,%esi
+        addl $8,%edi
+        decl %ecx
+        jnz _ConvertMMXpII32_16RGB565.L1
+
+_ConvertMMXpII32_16RGB565.L2: 
+        movl %edx,%ecx
+        andl $3,%ecx
+        jz _ConvertMMXpII32_16RGB565.L4
+_ConvertMMXpII32_16RGB565.L3: 
+        movb (%esi),%al
+        movb 1(%esi),%bh
+        movb 2(%esi),%ah
+        shrb $3,%al
+        andl $0x0F81F,%eax         # BYTE?
+        shrl $5,%ebx
+        andl $0x07E0,%ebx          # BYTE?
+        addl %ebx,%eax
+        movb %al,(%edi)
+        movb %ah,1(%edi)
+        addl $4,%esi
+        addl $2,%edi
+        decl %ecx
+        jnz _ConvertMMXpII32_16RGB565.L3
+
+_ConvertMMXpII32_16RGB565.L4: 
+        jmp _mmxreturn
+
+
+_ConvertMMXpII32_16BGR565: 
+
+        movq mmx32_rgb565_r,%mm5
+        movq mmx32_rgb565_g,%mm6
+        movq mmx32_rgb565_b,%mm7
+
+        movl %ecx,%edx
+        shrl $2,%ecx
+        jnz _ConvertMMXpII32_16BGR565.L1
+        jmp _ConvertMMXpII32_16BGR565.L2
+
+_ConvertMMXpII32_16BGR565.L1: 
+        movq (%esi),%mm0                # a r g b
+        movq %mm0,%mm1                  # a r g b
+        pand %mm6,%mm0                  # 0 0 g 0
+        movq %mm1,%mm3                  # a r g b
+        pand %mm5,%mm1                  # 0 r 0 0
+        pand %mm7,%mm3                  # 0 0 0 b
+
+        psllq $16,%mm3                  # 0 b 0 0
+        psrld $14,%mm1                  # 0 0 000000rr rrr00000
+        por %mm1,%mm0                   # 0 0 ggggggrr rrr00000
+        psrld $5,%mm0                   # 0 0 00000ggg gggrrrrr
+
+        movq 8(%esi),%mm4               # a r g b
+        movq %mm4,%mm2                  # a r g b
+        pand %mm6,%mm4                  # 0 0 g 0
+        movq %mm2,%mm1                  # a r g b
+        pand %mm5,%mm2                  # 0 r 0 0
+        pand %mm7,%mm1                  # 0 0 0 b
+
+        psllq $16,%mm1                  # 0 b 0 0
+        psrld $14,%mm2                  # 0 0 000000rr rrr00000
+        por %mm2,%mm4                   # 0 0 ggggggrr rrr00000
+        psrld $5,%mm4                   # 0 0 00000ggg gggrrrrr
+
+        packuswb %mm1,%mm3              # BBBBB000 00000000 bbbbb000 00000000
+        packssdw %mm4,%mm0              # 00000GGG GGGRRRRR 00000GGG GGGRRRRR
+        por %mm3,%mm0                   # BBBBBGGG GGGRRRRR bbbbbggg gggrrrrr
+        movq %mm0,(%edi)
+
+        addl $16,%esi
+        addl $8,%edi
+        decl %ecx
+        jnz _ConvertMMXpII32_16BGR565.L1
+
+_ConvertMMXpII32_16BGR565.L2: 
+        andl $3,%edx
+        jz _ConvertMMXpII32_16BGR565.L4
+_ConvertMMXpII32_16BGR565.L3: 
+        movb 2(%esi),%al
+        movb 1(%esi),%bh
+        movb (%esi),%ah
+        shrb $3,%al
+        andl $0x0F81F,%eax                 # BYTE ?
+        shrl $5,%ebx
+        andl $0x07E0,%ebx                  # BYTE ?
+        addl %ebx,%eax
+        movb %al,(%edi)
+        movb %ah,1(%edi)
+        addl $4,%esi
+        addl $2,%edi
+        decl %edx
+        jnz _ConvertMMXpII32_16BGR565.L3
+
+_ConvertMMXpII32_16BGR565.L4: 
+        jmp _mmxreturn
+
+_ConvertMMXpII32_16BGR555: 
+
+        # the 16BGR555 converter is identical to the RGB555 one,
+        # except it uses a different multiplier for the pmaddwd
+        # instruction.  cool huh.
+
+        movq mmx32_bgr555_mul,%mm7
+        jmp _convert_bgr555_cheat
+
+# This is the same as the Intel version.. they obviously went to
+# much more trouble to expand/coil the loop than I did, so theirs
+# would almost certainly be faster, even if only a little.
+# I did rename 'mmx32_rgb555_add' to 'mmx32_rgb555_mul', which is
+# (I think) a more accurate name..
+_ConvertMMXpII32_16RGB555: 
+
+        movq mmx32_rgb555_mul,%mm7
+_convert_bgr555_cheat: 
+        movq mmx32_rgb555_g,%mm6
+
+        movl %ecx,%edx                     # Save ecx 
+
+        andl $0x0fffffff8,%ecx             # clear lower three bits
+        jnz _convert_bgr555_cheat.L_OK
+        jmp _convert_bgr555_cheat.L2
+
+_convert_bgr555_cheat.L_OK: 
+
+        movq 8(%esi),%mm2
+
+        movq (%esi),%mm0
+        movq %mm2,%mm3
+
+        pand mmx32_rgb555_rb,%mm3
+        movq %mm0,%mm1
+
+        pand mmx32_rgb555_rb,%mm1
+        pmaddwd %mm7,%mm3
+
+        pmaddwd %mm7,%mm1
+        pand %mm6,%mm2
+
+_convert_bgr555_cheat.L1: 
+        movq 24(%esi),%mm4
+        pand %mm6,%mm0
+
+        movq 16(%esi),%mm5
+        por %mm2,%mm3
+
+        psrld $6,%mm3
+        por %mm0,%mm1
+
+        movq %mm4,%mm0
+        psrld $6,%mm1
+
+        pand mmx32_rgb555_rb,%mm0
+        packssdw %mm3,%mm1
+
+        movq %mm5,%mm3
+        pmaddwd %mm7,%mm0
+
+        pand mmx32_rgb555_rb,%mm3
+        pand %mm6,%mm4
+
+        movq %mm1,(%edi)
+        pmaddwd %mm7,%mm3
+
+        addl $32,%esi
+        por %mm0,%mm4
+
+        pand %mm6,%mm5
+        psrld $6,%mm4
+
+        movq 8(%esi),%mm2
+        por %mm3,%mm5
+
+        movq (%esi),%mm0
+        psrld $6,%mm5
+
+        movq %mm2,%mm3
+        movq %mm0,%mm1
+
+        pand mmx32_rgb555_rb,%mm3
+        packssdw %mm4,%mm5
+
+        pand mmx32_rgb555_rb,%mm1
+        pand %mm6,%mm2
+
+        movq %mm5,8(%edi)
+        pmaddwd %mm7,%mm3
+
+        pmaddwd %mm7,%mm1
+        addl $16,%edi
+
+        subl $8,%ecx
+        jz _convert_bgr555_cheat.L2
+        jmp _convert_bgr555_cheat.L1
+
+
+_convert_bgr555_cheat.L2: 
+        movl %edx,%ecx
+
+        andl $7,%ecx
+        jz _convert_bgr555_cheat.L4
+
+_convert_bgr555_cheat.L3: 
+        movl (%esi),%ebx
+        addl $4,%esi
+
+        movl %ebx,%eax
+        movl %ebx,%edx
+
+        shrl $3,%eax
+        shrl $6,%edx
+
+        andl $0b0000000000011111,%eax
+        andl $0b0000001111100000,%edx
+
+        shrl $9,%ebx
+
+        orl %edx,%eax
+
+        andl $0b0111110000000000,%ebx
+
+        orl %ebx,%eax
+
+        movw %ax,(%edi)
+        addl $2,%edi
+
+        decl %ecx
+        jnz _convert_bgr555_cheat.L3
+
+_convert_bgr555_cheat.L4: 
+        jmp _mmxreturn
+
+
+

+ 163 - 0
packages/hermes/src/i386/mmxp_32.as

@@ -0,0 +1,163 @@
+#
+# MMX format converters for HERMES
+# Copyright (c) 1998 Christian Nentwich ([email protected])
+# This source code is licensed under the GNU LGPL
+# 
+# Please refer to the file COPYING.LIB contained in the distribution for
+# licensing conditions          
+#
+# COPYRIGHT NOTICE
+# 
+# This file partly contains code that is (c) Intel Corporation, specifically
+# the mode detection routine, and the converter to 15 bit (8 pixel
+# conversion routine from the mmx programming tutorial pages).
+# 
+
+#BITS 32
+
+
+.globl _ConvertMMXp32_16RGB555
+
+.extern _mmxreturn
+
+.data
+
+.align 8
+
+mmx32_rgb555_rb: .long 0x00f800f8,0x00f800f8 # Constants for conversion routines 
+mmx32_rgb555_add: .long 0x20000008,0x20000008
+mmx32_rgb555_g: .long 0x0000f800,0x0000f800
+
+
+
+.text
+
+
+
+## Gone for now, it didnt draw correctly AND was slower than the x86 routine 
+_ConvertMMXp32_16RGB565: 
+
+        jmp _mmxreturn
+
+
+
+
+_ConvertMMXp32_16RGB555: 
+
+        movq mmx32_rgb555_add,%mm7
+        movq mmx32_rgb555_g,%mm6
+
+        movl %ecx,%edx                     # Save ecx 
+
+        andl $0x0fffffff8,%ecx             # clear lower three bits
+        jnz _ConvertMMXp32_16RGB555.L_OK
+        jmp _ConvertMMXp32_16RGB555.L2
+
+_ConvertMMXp32_16RGB555.L_OK: 
+
+        movq 8(%esi),%mm2
+
+        movq (%esi),%mm0
+        movq %mm2,%mm3
+
+        pand mmx32_rgb555_rb,%mm3
+        movq %mm0,%mm1
+
+        pand mmx32_rgb555_rb,%mm1
+        pmaddwd %mm7,%mm3
+
+        pmaddwd %mm7,%mm1
+        pand %mm6,%mm2
+
+_ConvertMMXp32_16RGB555.L1: 
+        movq 24(%esi),%mm4
+        pand %mm6,%mm0
+
+        movq 16(%esi),%mm5
+        por %mm2,%mm3
+
+        psrld $6,%mm3
+        por %mm0,%mm1
+
+        movq %mm4,%mm0
+        psrld $6,%mm1
+
+        pand mmx32_rgb555_rb,%mm0
+        packssdw %mm3,%mm1
+
+        movq %mm5,%mm3
+        pmaddwd %mm7,%mm0
+
+        pand mmx32_rgb555_rb,%mm3
+        pand %mm6,%mm4
+
+        movq %mm1,(%edi)
+        pmaddwd %mm7,%mm3
+
+        addl $32,%esi
+        por %mm0,%mm4
+
+        pand %mm6,%mm5
+        psrld $6,%mm4
+
+        movq 8(%esi),%mm2
+        por %mm3,%mm5
+
+        movq (%esi),%mm0
+        psrld $6,%mm5
+
+        movq %mm2,%mm3
+        movq %mm0,%mm1
+
+        pand mmx32_rgb555_rb,%mm3
+        packssdw %mm4,%mm5
+
+        pand mmx32_rgb555_rb,%mm1
+        pand %mm6,%mm2
+
+        movq %mm5,8(%edi)
+        pmaddwd %mm7,%mm3
+
+        pmaddwd %mm7,%mm1
+        addl $16,%edi
+
+        subl $8,%ecx
+        jz _ConvertMMXp32_16RGB555.L2
+        jmp _ConvertMMXp32_16RGB555.L1
+
+
+_ConvertMMXp32_16RGB555.L2: 
+        movl %edx,%ecx
+
+        andl $7,%ecx
+        jz _ConvertMMXp32_16RGB555.L4
+
+_ConvertMMXp32_16RGB555.L3: 
+        movl (%esi),%ebx
+        addl $4,%esi
+
+        movl %ebx,%eax
+        movl %ebx,%edx
+
+        shrl $3,%eax
+        shrl $6,%edx
+
+        andl $0b0000000000011111,%eax
+        andl $0b0000001111100000,%edx
+
+        shrl $9,%ebx
+
+        orl %edx,%eax
+
+        andl $0b0111110000000000,%ebx
+
+        orl %ebx,%eax
+
+        movw %ax,(%edi)
+        addl $2,%edi
+
+        decl %ecx
+        jnz _ConvertMMXp32_16RGB555.L3
+
+_ConvertMMXp32_16RGB555.L4: 
+        jmp _mmxreturn

+ 2059 - 0
packages/hermes/src/i386/x8616lut.as

@@ -0,0 +1,2059 @@
+
+.data
+
+_ConvertX86p16_32RGB888_LUT_X86:
+		.long 0x00000
+		.long 0x00000
+		.long 0x00008
+		.long 0x02000
+		.long 0x00010
+		.long 0x04000
+		.long 0x00018
+		.long 0x06100
+		.long 0x00020
+		.long 0x08100
+		.long 0x00029
+		.long 0x0a100
+		.long 0x00031
+		.long 0x0c200
+		.long 0x00039
+		.long 0x0e200
+		.long 0x00041
+		.long 0x80000
+		.long 0x0004a
+		.long 0x82000
+		.long 0x00052
+		.long 0x84000
+		.long 0x0005a
+		.long 0x86100
+		.long 0x00062
+		.long 0x88100
+		.long 0x0006a
+		.long 0x8a100
+		.long 0x00073
+		.long 0x8c200
+		.long 0x0007b
+		.long 0x8e200
+		.long 0x00083
+		.long 0x100000
+		.long 0x0008b
+		.long 0x102000
+		.long 0x00094
+		.long 0x104000
+		.long 0x0009c
+		.long 0x106100
+		.long 0x000a4
+		.long 0x108100
+		.long 0x000ac
+		.long 0x10a100
+		.long 0x000b4
+		.long 0x10c200
+		.long 0x000bd
+		.long 0x10e200
+		.long 0x000c5
+		.long 0x180000
+		.long 0x000cd
+		.long 0x182000
+		.long 0x000d5
+		.long 0x184000
+		.long 0x000de
+		.long 0x186100
+		.long 0x000e6
+		.long 0x188100
+		.long 0x000ee
+		.long 0x18a100
+		.long 0x000f6
+		.long 0x18c200
+		.long 0x000ff
+		.long 0x18e200
+		.long 0x00400
+		.long 0x200000
+		.long 0x00408
+		.long 0x202000
+		.long 0x00410
+		.long 0x204000
+		.long 0x00418
+		.long 0x206100
+		.long 0x00420
+		.long 0x208100
+		.long 0x00429
+		.long 0x20a100
+		.long 0x00431
+		.long 0x20c200
+		.long 0x00439
+		.long 0x20e200
+		.long 0x00441
+		.long 0x290000
+		.long 0x0044a
+		.long 0x292000
+		.long 0x00452
+		.long 0x294000
+		.long 0x0045a
+		.long 0x296100
+		.long 0x00462
+		.long 0x298100
+		.long 0x0046a
+		.long 0x29a100
+		.long 0x00473
+		.long 0x29c200
+		.long 0x0047b
+		.long 0x29e200
+		.long 0x00483
+		.long 0x310000
+		.long 0x0048b
+		.long 0x312000
+		.long 0x00494
+		.long 0x314000
+		.long 0x0049c
+		.long 0x316100
+		.long 0x004a4
+		.long 0x318100
+		.long 0x004ac
+		.long 0x31a100
+		.long 0x004b4
+		.long 0x31c200
+		.long 0x004bd
+		.long 0x31e200
+		.long 0x004c5
+		.long 0x390000
+		.long 0x004cd
+		.long 0x392000
+		.long 0x004d5
+		.long 0x394000
+		.long 0x004de
+		.long 0x396100
+		.long 0x004e6
+		.long 0x398100
+		.long 0x004ee
+		.long 0x39a100
+		.long 0x004f6
+		.long 0x39c200
+		.long 0x004ff
+		.long 0x39e200
+		.long 0x00800
+		.long 0x410000
+		.long 0x00808
+		.long 0x412000
+		.long 0x00810
+		.long 0x414000
+		.long 0x00818
+		.long 0x416100
+		.long 0x00820
+		.long 0x418100
+		.long 0x00829
+		.long 0x41a100
+		.long 0x00831
+		.long 0x41c200
+		.long 0x00839
+		.long 0x41e200
+		.long 0x00841
+		.long 0x4a0000
+		.long 0x0084a
+		.long 0x4a2000
+		.long 0x00852
+		.long 0x4a4000
+		.long 0x0085a
+		.long 0x4a6100
+		.long 0x00862
+		.long 0x4a8100
+		.long 0x0086a
+		.long 0x4aa100
+		.long 0x00873
+		.long 0x4ac200
+		.long 0x0087b
+		.long 0x4ae200
+		.long 0x00883
+		.long 0x520000
+		.long 0x0088b
+		.long 0x522000
+		.long 0x00894
+		.long 0x524000
+		.long 0x0089c
+		.long 0x526100
+		.long 0x008a4
+		.long 0x528100
+		.long 0x008ac
+		.long 0x52a100
+		.long 0x008b4
+		.long 0x52c200
+		.long 0x008bd
+		.long 0x52e200
+		.long 0x008c5
+		.long 0x5a0000
+		.long 0x008cd
+		.long 0x5a2000
+		.long 0x008d5
+		.long 0x5a4000
+		.long 0x008de
+		.long 0x5a6100
+		.long 0x008e6
+		.long 0x5a8100
+		.long 0x008ee
+		.long 0x5aa100
+		.long 0x008f6
+		.long 0x5ac200
+		.long 0x008ff
+		.long 0x5ae200
+		.long 0x00c00
+		.long 0x620000
+		.long 0x00c08
+		.long 0x622000
+		.long 0x00c10
+		.long 0x624000
+		.long 0x00c18
+		.long 0x626100
+		.long 0x00c20
+		.long 0x628100
+		.long 0x00c29
+		.long 0x62a100
+		.long 0x00c31
+		.long 0x62c200
+		.long 0x00c39
+		.long 0x62e200
+		.long 0x00c41
+		.long 0x6a0000
+		.long 0x00c4a
+		.long 0x6a2000
+		.long 0x00c52
+		.long 0x6a4000
+		.long 0x00c5a
+		.long 0x6a6100
+		.long 0x00c62
+		.long 0x6a8100
+		.long 0x00c6a
+		.long 0x6aa100
+		.long 0x00c73
+		.long 0x6ac200
+		.long 0x00c7b
+		.long 0x6ae200
+		.long 0x00c83
+		.long 0x730000
+		.long 0x00c8b
+		.long 0x732000
+		.long 0x00c94
+		.long 0x734000
+		.long 0x00c9c
+		.long 0x736100
+		.long 0x00ca4
+		.long 0x738100
+		.long 0x00cac
+		.long 0x73a100
+		.long 0x00cb4
+		.long 0x73c200
+		.long 0x00cbd
+		.long 0x73e200
+		.long 0x00cc5
+		.long 0x7b0000
+		.long 0x00ccd
+		.long 0x7b2000
+		.long 0x00cd5
+		.long 0x7b4000
+		.long 0x00cde
+		.long 0x7b6100
+		.long 0x00ce6
+		.long 0x7b8100
+		.long 0x00cee
+		.long 0x7ba100
+		.long 0x00cf6
+		.long 0x7bc200
+		.long 0x00cff
+		.long 0x7be200
+		.long 0x01000
+		.long 0x830000
+		.long 0x01008
+		.long 0x832000
+		.long 0x01010
+		.long 0x834000
+		.long 0x01018
+		.long 0x836100
+		.long 0x01020
+		.long 0x838100
+		.long 0x01029
+		.long 0x83a100
+		.long 0x01031
+		.long 0x83c200
+		.long 0x01039
+		.long 0x83e200
+		.long 0x01041
+		.long 0x8b0000
+		.long 0x0104a
+		.long 0x8b2000
+		.long 0x01052
+		.long 0x8b4000
+		.long 0x0105a
+		.long 0x8b6100
+		.long 0x01062
+		.long 0x8b8100
+		.long 0x0106a
+		.long 0x8ba100
+		.long 0x01073
+		.long 0x8bc200
+		.long 0x0107b
+		.long 0x8be200
+		.long 0x01083
+		.long 0x940000
+		.long 0x0108b
+		.long 0x942000
+		.long 0x01094
+		.long 0x944000
+		.long 0x0109c
+		.long 0x946100
+		.long 0x010a4
+		.long 0x948100
+		.long 0x010ac
+		.long 0x94a100
+		.long 0x010b4
+		.long 0x94c200
+		.long 0x010bd
+		.long 0x94e200
+		.long 0x010c5
+		.long 0x9c0000
+		.long 0x010cd
+		.long 0x9c2000
+		.long 0x010d5
+		.long 0x9c4000
+		.long 0x010de
+		.long 0x9c6100
+		.long 0x010e6
+		.long 0x9c8100
+		.long 0x010ee
+		.long 0x9ca100
+		.long 0x010f6
+		.long 0x9cc200
+		.long 0x010ff
+		.long 0x9ce200
+		.long 0x01400
+		.long 0xa40000
+		.long 0x01408
+		.long 0xa42000
+		.long 0x01410
+		.long 0xa44000
+		.long 0x01418
+		.long 0xa46100
+		.long 0x01420
+		.long 0xa48100
+		.long 0x01429
+		.long 0xa4a100
+		.long 0x01431
+		.long 0xa4c200
+		.long 0x01439
+		.long 0xa4e200
+		.long 0x01441
+		.long 0xac0000
+		.long 0x0144a
+		.long 0xac2000
+		.long 0x01452
+		.long 0xac4000
+		.long 0x0145a
+		.long 0xac6100
+		.long 0x01462
+		.long 0xac8100
+		.long 0x0146a
+		.long 0xaca100
+		.long 0x01473
+		.long 0xacc200
+		.long 0x0147b
+		.long 0xace200
+		.long 0x01483
+		.long 0xb40000
+		.long 0x0148b
+		.long 0xb42000
+		.long 0x01494
+		.long 0xb44000
+		.long 0x0149c
+		.long 0xb46100
+		.long 0x014a4
+		.long 0xb48100
+		.long 0x014ac
+		.long 0xb4a100
+		.long 0x014b4
+		.long 0xb4c200
+		.long 0x014bd
+		.long 0xb4e200
+		.long 0x014c5
+		.long 0xbd0000
+		.long 0x014cd
+		.long 0xbd2000
+		.long 0x014d5
+		.long 0xbd4000
+		.long 0x014de
+		.long 0xbd6100
+		.long 0x014e6
+		.long 0xbd8100
+		.long 0x014ee
+		.long 0xbda100
+		.long 0x014f6
+		.long 0xbdc200
+		.long 0x014ff
+		.long 0xbde200
+		.long 0x01800
+		.long 0xc50000
+		.long 0x01808
+		.long 0xc52000
+		.long 0x01810
+		.long 0xc54000
+		.long 0x01818
+		.long 0xc56100
+		.long 0x01820
+		.long 0xc58100
+		.long 0x01829
+		.long 0xc5a100
+		.long 0x01831
+		.long 0xc5c200
+		.long 0x01839
+		.long 0xc5e200
+		.long 0x01841
+		.long 0xcd0000
+		.long 0x0184a
+		.long 0xcd2000
+		.long 0x01852
+		.long 0xcd4000
+		.long 0x0185a
+		.long 0xcd6100
+		.long 0x01862
+		.long 0xcd8100
+		.long 0x0186a
+		.long 0xcda100
+		.long 0x01873
+		.long 0xcdc200
+		.long 0x0187b
+		.long 0xcde200
+		.long 0x01883
+		.long 0xd50000
+		.long 0x0188b
+		.long 0xd52000
+		.long 0x01894
+		.long 0xd54000
+		.long 0x0189c
+		.long 0xd56100
+		.long 0x018a4
+		.long 0xd58100
+		.long 0x018ac
+		.long 0xd5a100
+		.long 0x018b4
+		.long 0xd5c200
+		.long 0x018bd
+		.long 0xd5e200
+		.long 0x018c5
+		.long 0xde0000
+		.long 0x018cd
+		.long 0xde2000
+		.long 0x018d5
+		.long 0xde4000
+		.long 0x018de
+		.long 0xde6100
+		.long 0x018e6
+		.long 0xde8100
+		.long 0x018ee
+		.long 0xdea100
+		.long 0x018f6
+		.long 0xdec200
+		.long 0x018ff
+		.long 0xdee200
+		.long 0x01c00
+		.long 0xe60000
+		.long 0x01c08
+		.long 0xe62000
+		.long 0x01c10
+		.long 0xe64000
+		.long 0x01c18
+		.long 0xe66100
+		.long 0x01c20
+		.long 0xe68100
+		.long 0x01c29
+		.long 0xe6a100
+		.long 0x01c31
+		.long 0xe6c200
+		.long 0x01c39
+		.long 0xe6e200
+		.long 0x01c41
+		.long 0xee0000
+		.long 0x01c4a
+		.long 0xee2000
+		.long 0x01c52
+		.long 0xee4000
+		.long 0x01c5a
+		.long 0xee6100
+		.long 0x01c62
+		.long 0xee8100
+		.long 0x01c6a
+		.long 0xeea100
+		.long 0x01c73
+		.long 0xeec200
+		.long 0x01c7b
+		.long 0xeee200
+		.long 0x01c83
+		.long 0xf60000
+		.long 0x01c8b
+		.long 0xf62000
+		.long 0x01c94
+		.long 0xf64000
+		.long 0x01c9c
+		.long 0xf66100
+		.long 0x01ca4
+		.long 0xf68100
+		.long 0x01cac
+		.long 0xf6a100
+		.long 0x01cb4
+		.long 0xf6c200
+		.long 0x01cbd
+		.long 0xf6e200
+		.long 0x01cc5
+		.long 0xff0000
+		.long 0x01ccd
+		.long 0xff2000
+		.long 0x01cd5
+		.long 0xff4000
+		.long 0x01cde
+		.long 0xff6100
+		.long 0x01ce6
+		.long 0xff8100
+		.long 0x01cee
+		.long 0xffa100
+		.long 0x01cf6
+		.long 0xffc200
+		.long 0x01cff
+		.long 0xffe200
+
+_ConvertX86p16_32BGR888_LUT_X86:
+		.long 0x00000
+		.long 0x00000
+		.long 0x80000
+		.long 0x02000
+		.long 0x100000
+		.long 0x04000
+		.long 0x180000
+		.long 0x06100
+		.long 0x200000
+		.long 0x08100
+		.long 0x290000
+		.long 0x0a100
+		.long 0x310000
+		.long 0x0c200
+		.long 0x390000
+		.long 0x0e200
+		.long 0x410000
+		.long 0x00008
+		.long 0x4a0000
+		.long 0x02008
+		.long 0x520000
+		.long 0x04008
+		.long 0x5a0000
+		.long 0x06108
+		.long 0x620000
+		.long 0x08108
+		.long 0x6a0000
+		.long 0x0a108
+		.long 0x730000
+		.long 0x0c208
+		.long 0x7b0000
+		.long 0x0e208
+		.long 0x830000
+		.long 0x00010
+		.long 0x8b0000
+		.long 0x02010
+		.long 0x940000
+		.long 0x04010
+		.long 0x9c0000
+		.long 0x06110
+		.long 0xa40000
+		.long 0x08110
+		.long 0xac0000
+		.long 0x0a110
+		.long 0xb40000
+		.long 0x0c210
+		.long 0xbd0000
+		.long 0x0e210
+		.long 0xc50000
+		.long 0x00018
+		.long 0xcd0000
+		.long 0x02018
+		.long 0xd50000
+		.long 0x04018
+		.long 0xde0000
+		.long 0x06118
+		.long 0xe60000
+		.long 0x08118
+		.long 0xee0000
+		.long 0x0a118
+		.long 0xf60000
+		.long 0x0c218
+		.long 0xff0000
+		.long 0x0e218
+		.long 0x00400
+		.long 0x00020
+		.long 0x80400
+		.long 0x02020
+		.long 0x100400
+		.long 0x04020
+		.long 0x180400
+		.long 0x06120
+		.long 0x200400
+		.long 0x08120
+		.long 0x290400
+		.long 0x0a120
+		.long 0x310400
+		.long 0x0c220
+		.long 0x390400
+		.long 0x0e220
+		.long 0x410400
+		.long 0x00029
+		.long 0x4a0400
+		.long 0x02029
+		.long 0x520400
+		.long 0x04029
+		.long 0x5a0400
+		.long 0x06129
+		.long 0x620400
+		.long 0x08129
+		.long 0x6a0400
+		.long 0x0a129
+		.long 0x730400
+		.long 0x0c229
+		.long 0x7b0400
+		.long 0x0e229
+		.long 0x830400
+		.long 0x00031
+		.long 0x8b0400
+		.long 0x02031
+		.long 0x940400
+		.long 0x04031
+		.long 0x9c0400
+		.long 0x06131
+		.long 0xa40400
+		.long 0x08131
+		.long 0xac0400
+		.long 0x0a131
+		.long 0xb40400
+		.long 0x0c231
+		.long 0xbd0400
+		.long 0x0e231
+		.long 0xc50400
+		.long 0x00039
+		.long 0xcd0400
+		.long 0x02039
+		.long 0xd50400
+		.long 0x04039
+		.long 0xde0400
+		.long 0x06139
+		.long 0xe60400
+		.long 0x08139
+		.long 0xee0400
+		.long 0x0a139
+		.long 0xf60400
+		.long 0x0c239
+		.long 0xff0400
+		.long 0x0e239
+		.long 0x00800
+		.long 0x00041
+		.long 0x80800
+		.long 0x02041
+		.long 0x100800
+		.long 0x04041
+		.long 0x180800
+		.long 0x06141
+		.long 0x200800
+		.long 0x08141
+		.long 0x290800
+		.long 0x0a141
+		.long 0x310800
+		.long 0x0c241
+		.long 0x390800
+		.long 0x0e241
+		.long 0x410800
+		.long 0x0004a
+		.long 0x4a0800
+		.long 0x0204a
+		.long 0x520800
+		.long 0x0404a
+		.long 0x5a0800
+		.long 0x0614a
+		.long 0x620800
+		.long 0x0814a
+		.long 0x6a0800
+		.long 0x0a14a
+		.long 0x730800
+		.long 0x0c24a
+		.long 0x7b0800
+		.long 0x0e24a
+		.long 0x830800
+		.long 0x00052
+		.long 0x8b0800
+		.long 0x02052
+		.long 0x940800
+		.long 0x04052
+		.long 0x9c0800
+		.long 0x06152
+		.long 0xa40800
+		.long 0x08152
+		.long 0xac0800
+		.long 0x0a152
+		.long 0xb40800
+		.long 0x0c252
+		.long 0xbd0800
+		.long 0x0e252
+		.long 0xc50800
+		.long 0x0005a
+		.long 0xcd0800
+		.long 0x0205a
+		.long 0xd50800
+		.long 0x0405a
+		.long 0xde0800
+		.long 0x0615a
+		.long 0xe60800
+		.long 0x0815a
+		.long 0xee0800
+		.long 0x0a15a
+		.long 0xf60800
+		.long 0x0c25a
+		.long 0xff0800
+		.long 0x0e25a
+		.long 0x00c00
+		.long 0x00062
+		.long 0x80c00
+		.long 0x02062
+		.long 0x100c00
+		.long 0x04062
+		.long 0x180c00
+		.long 0x06162
+		.long 0x200c00
+		.long 0x08162
+		.long 0x290c00
+		.long 0x0a162
+		.long 0x310c00
+		.long 0x0c262
+		.long 0x390c00
+		.long 0x0e262
+		.long 0x410c00
+		.long 0x0006a
+		.long 0x4a0c00
+		.long 0x0206a
+		.long 0x520c00
+		.long 0x0406a
+		.long 0x5a0c00
+		.long 0x0616a
+		.long 0x620c00
+		.long 0x0816a
+		.long 0x6a0c00
+		.long 0x0a16a
+		.long 0x730c00
+		.long 0x0c26a
+		.long 0x7b0c00
+		.long 0x0e26a
+		.long 0x830c00
+		.long 0x00073
+		.long 0x8b0c00
+		.long 0x02073
+		.long 0x940c00
+		.long 0x04073
+		.long 0x9c0c00
+		.long 0x06173
+		.long 0xa40c00
+		.long 0x08173
+		.long 0xac0c00
+		.long 0x0a173
+		.long 0xb40c00
+		.long 0x0c273
+		.long 0xbd0c00
+		.long 0x0e273
+		.long 0xc50c00
+		.long 0x0007b
+		.long 0xcd0c00
+		.long 0x0207b
+		.long 0xd50c00
+		.long 0x0407b
+		.long 0xde0c00
+		.long 0x0617b
+		.long 0xe60c00
+		.long 0x0817b
+		.long 0xee0c00
+		.long 0x0a17b
+		.long 0xf60c00
+		.long 0x0c27b
+		.long 0xff0c00
+		.long 0x0e27b
+		.long 0x01000
+		.long 0x00083
+		.long 0x81000
+		.long 0x02083
+		.long 0x101000
+		.long 0x04083
+		.long 0x181000
+		.long 0x06183
+		.long 0x201000
+		.long 0x08183
+		.long 0x291000
+		.long 0x0a183
+		.long 0x311000
+		.long 0x0c283
+		.long 0x391000
+		.long 0x0e283
+		.long 0x411000
+		.long 0x0008b
+		.long 0x4a1000
+		.long 0x0208b
+		.long 0x521000
+		.long 0x0408b
+		.long 0x5a1000
+		.long 0x0618b
+		.long 0x621000
+		.long 0x0818b
+		.long 0x6a1000
+		.long 0x0a18b
+		.long 0x731000
+		.long 0x0c28b
+		.long 0x7b1000
+		.long 0x0e28b
+		.long 0x831000
+		.long 0x00094
+		.long 0x8b1000
+		.long 0x02094
+		.long 0x941000
+		.long 0x04094
+		.long 0x9c1000
+		.long 0x06194
+		.long 0xa41000
+		.long 0x08194
+		.long 0xac1000
+		.long 0x0a194
+		.long 0xb41000
+		.long 0x0c294
+		.long 0xbd1000
+		.long 0x0e294
+		.long 0xc51000
+		.long 0x0009c
+		.long 0xcd1000
+		.long 0x0209c
+		.long 0xd51000
+		.long 0x0409c
+		.long 0xde1000
+		.long 0x0619c
+		.long 0xe61000
+		.long 0x0819c
+		.long 0xee1000
+		.long 0x0a19c
+		.long 0xf61000
+		.long 0x0c29c
+		.long 0xff1000
+		.long 0x0e29c
+		.long 0x01400
+		.long 0x000a4
+		.long 0x81400
+		.long 0x020a4
+		.long 0x101400
+		.long 0x040a4
+		.long 0x181400
+		.long 0x061a4
+		.long 0x201400
+		.long 0x081a4
+		.long 0x291400
+		.long 0x0a1a4
+		.long 0x311400
+		.long 0x0c2a4
+		.long 0x391400
+		.long 0x0e2a4
+		.long 0x411400
+		.long 0x000ac
+		.long 0x4a1400
+		.long 0x020ac
+		.long 0x521400
+		.long 0x040ac
+		.long 0x5a1400
+		.long 0x061ac
+		.long 0x621400
+		.long 0x081ac
+		.long 0x6a1400
+		.long 0x0a1ac
+		.long 0x731400
+		.long 0x0c2ac
+		.long 0x7b1400
+		.long 0x0e2ac
+		.long 0x831400
+		.long 0x000b4
+		.long 0x8b1400
+		.long 0x020b4
+		.long 0x941400
+		.long 0x040b4
+		.long 0x9c1400
+		.long 0x061b4
+		.long 0xa41400
+		.long 0x081b4
+		.long 0xac1400
+		.long 0x0a1b4
+		.long 0xb41400
+		.long 0x0c2b4
+		.long 0xbd1400
+		.long 0x0e2b4
+		.long 0xc51400
+		.long 0x000bd
+		.long 0xcd1400
+		.long 0x020bd
+		.long 0xd51400
+		.long 0x040bd
+		.long 0xde1400
+		.long 0x061bd
+		.long 0xe61400
+		.long 0x081bd
+		.long 0xee1400
+		.long 0x0a1bd
+		.long 0xf61400
+		.long 0x0c2bd
+		.long 0xff1400
+		.long 0x0e2bd
+		.long 0x01800
+		.long 0x000c5
+		.long 0x81800
+		.long 0x020c5
+		.long 0x101800
+		.long 0x040c5
+		.long 0x181800
+		.long 0x061c5
+		.long 0x201800
+		.long 0x081c5
+		.long 0x291800
+		.long 0x0a1c5
+		.long 0x311800
+		.long 0x0c2c5
+		.long 0x391800
+		.long 0x0e2c5
+		.long 0x411800
+		.long 0x000cd
+		.long 0x4a1800
+		.long 0x020cd
+		.long 0x521800
+		.long 0x040cd
+		.long 0x5a1800
+		.long 0x061cd
+		.long 0x621800
+		.long 0x081cd
+		.long 0x6a1800
+		.long 0x0a1cd
+		.long 0x731800
+		.long 0x0c2cd
+		.long 0x7b1800
+		.long 0x0e2cd
+		.long 0x831800
+		.long 0x000d5
+		.long 0x8b1800
+		.long 0x020d5
+		.long 0x941800
+		.long 0x040d5
+		.long 0x9c1800
+		.long 0x061d5
+		.long 0xa41800
+		.long 0x081d5
+		.long 0xac1800
+		.long 0x0a1d5
+		.long 0xb41800
+		.long 0x0c2d5
+		.long 0xbd1800
+		.long 0x0e2d5
+		.long 0xc51800
+		.long 0x000de
+		.long 0xcd1800
+		.long 0x020de
+		.long 0xd51800
+		.long 0x040de
+		.long 0xde1800
+		.long 0x061de
+		.long 0xe61800
+		.long 0x081de
+		.long 0xee1800
+		.long 0x0a1de
+		.long 0xf61800
+		.long 0x0c2de
+		.long 0xff1800
+		.long 0x0e2de
+		.long 0x01c00
+		.long 0x000e6
+		.long 0x81c00
+		.long 0x020e6
+		.long 0x101c00
+		.long 0x040e6
+		.long 0x181c00
+		.long 0x061e6
+		.long 0x201c00
+		.long 0x081e6
+		.long 0x291c00
+		.long 0x0a1e6
+		.long 0x311c00
+		.long 0x0c2e6
+		.long 0x391c00
+		.long 0x0e2e6
+		.long 0x411c00
+		.long 0x000ee
+		.long 0x4a1c00
+		.long 0x020ee
+		.long 0x521c00
+		.long 0x040ee
+		.long 0x5a1c00
+		.long 0x061ee
+		.long 0x621c00
+		.long 0x081ee
+		.long 0x6a1c00
+		.long 0x0a1ee
+		.long 0x731c00
+		.long 0x0c2ee
+		.long 0x7b1c00
+		.long 0x0e2ee
+		.long 0x831c00
+		.long 0x000f6
+		.long 0x8b1c00
+		.long 0x020f6
+		.long 0x941c00
+		.long 0x040f6
+		.long 0x9c1c00
+		.long 0x061f6
+		.long 0xa41c00
+		.long 0x081f6
+		.long 0xac1c00
+		.long 0x0a1f6
+		.long 0xb41c00
+		.long 0x0c2f6
+		.long 0xbd1c00
+		.long 0x0e2f6
+		.long 0xc51c00
+		.long 0x000ff
+		.long 0xcd1c00
+		.long 0x020ff
+		.long 0xd51c00
+		.long 0x040ff
+		.long 0xde1c00
+		.long 0x061ff
+		.long 0xe61c00
+		.long 0x081ff
+		.long 0xee1c00
+		.long 0x0a1ff
+		.long 0xf61c00
+		.long 0x0c2ff
+		.long 0xff1c00
+		.long 0x0e2ff
+
+_ConvertX86p16_32RGBA888_LUT_X86:
+		.long 0x00000
+		.long 0x000ff
+		.long 0x00800
+		.long 0x2000ff
+		.long 0x01000
+		.long 0x4000ff
+		.long 0x01800
+		.long 0x6100ff
+		.long 0x02000
+		.long 0x8100ff
+		.long 0x02900
+		.long 0xa100ff
+		.long 0x03100
+		.long 0xc200ff
+		.long 0x03900
+		.long 0xe200ff
+		.long 0x04100
+		.long 0x80000ff
+		.long 0x04a00
+		.long 0x82000ff
+		.long 0x05200
+		.long 0x84000ff
+		.long 0x05a00
+		.long 0x86100ff
+		.long 0x06200
+		.long 0x88100ff
+		.long 0x06a00
+		.long 0x8a100ff
+		.long 0x07300
+		.long 0x8c200ff
+		.long 0x07b00
+		.long 0x8e200ff
+		.long 0x08300
+		.long 0x100000ff
+		.long 0x08b00
+		.long 0x102000ff
+		.long 0x09400
+		.long 0x104000ff
+		.long 0x09c00
+		.long 0x106100ff
+		.long 0x0a400
+		.long 0x108100ff
+		.long 0x0ac00
+		.long 0x10a100ff
+		.long 0x0b400
+		.long 0x10c200ff
+		.long 0x0bd00
+		.long 0x10e200ff
+		.long 0x0c500
+		.long 0x180000ff
+		.long 0x0cd00
+		.long 0x182000ff
+		.long 0x0d500
+		.long 0x184000ff
+		.long 0x0de00
+		.long 0x186100ff
+		.long 0x0e600
+		.long 0x188100ff
+		.long 0x0ee00
+		.long 0x18a100ff
+		.long 0x0f600
+		.long 0x18c200ff
+		.long 0x0ff00
+		.long 0x18e200ff
+		.long 0x40000
+		.long 0x200000ff
+		.long 0x40800
+		.long 0x202000ff
+		.long 0x41000
+		.long 0x204000ff
+		.long 0x41800
+		.long 0x206100ff
+		.long 0x42000
+		.long 0x208100ff
+		.long 0x42900
+		.long 0x20a100ff
+		.long 0x43100
+		.long 0x20c200ff
+		.long 0x43900
+		.long 0x20e200ff
+		.long 0x44100
+		.long 0x290000ff
+		.long 0x44a00
+		.long 0x292000ff
+		.long 0x45200
+		.long 0x294000ff
+		.long 0x45a00
+		.long 0x296100ff
+		.long 0x46200
+		.long 0x298100ff
+		.long 0x46a00
+		.long 0x29a100ff
+		.long 0x47300
+		.long 0x29c200ff
+		.long 0x47b00
+		.long 0x29e200ff
+		.long 0x48300
+		.long 0x310000ff
+		.long 0x48b00
+		.long 0x312000ff
+		.long 0x49400
+		.long 0x314000ff
+		.long 0x49c00
+		.long 0x316100ff
+		.long 0x4a400
+		.long 0x318100ff
+		.long 0x4ac00
+		.long 0x31a100ff
+		.long 0x4b400
+		.long 0x31c200ff
+		.long 0x4bd00
+		.long 0x31e200ff
+		.long 0x4c500
+		.long 0x390000ff
+		.long 0x4cd00
+		.long 0x392000ff
+		.long 0x4d500
+		.long 0x394000ff
+		.long 0x4de00
+		.long 0x396100ff
+		.long 0x4e600
+		.long 0x398100ff
+		.long 0x4ee00
+		.long 0x39a100ff
+		.long 0x4f600
+		.long 0x39c200ff
+		.long 0x4ff00
+		.long 0x39e200ff
+		.long 0x80000
+		.long 0x410000ff
+		.long 0x80800
+		.long 0x412000ff
+		.long 0x81000
+		.long 0x414000ff
+		.long 0x81800
+		.long 0x416100ff
+		.long 0x82000
+		.long 0x418100ff
+		.long 0x82900
+		.long 0x41a100ff
+		.long 0x83100
+		.long 0x41c200ff
+		.long 0x83900
+		.long 0x41e200ff
+		.long 0x84100
+		.long 0x4a0000ff
+		.long 0x84a00
+		.long 0x4a2000ff
+		.long 0x85200
+		.long 0x4a4000ff
+		.long 0x85a00
+		.long 0x4a6100ff
+		.long 0x86200
+		.long 0x4a8100ff
+		.long 0x86a00
+		.long 0x4aa100ff
+		.long 0x87300
+		.long 0x4ac200ff
+		.long 0x87b00
+		.long 0x4ae200ff
+		.long 0x88300
+		.long 0x520000ff
+		.long 0x88b00
+		.long 0x522000ff
+		.long 0x89400
+		.long 0x524000ff
+		.long 0x89c00
+		.long 0x526100ff
+		.long 0x8a400
+		.long 0x528100ff
+		.long 0x8ac00
+		.long 0x52a100ff
+		.long 0x8b400
+		.long 0x52c200ff
+		.long 0x8bd00
+		.long 0x52e200ff
+		.long 0x8c500
+		.long 0x5a0000ff
+		.long 0x8cd00
+		.long 0x5a2000ff
+		.long 0x8d500
+		.long 0x5a4000ff
+		.long 0x8de00
+		.long 0x5a6100ff
+		.long 0x8e600
+		.long 0x5a8100ff
+		.long 0x8ee00
+		.long 0x5aa100ff
+		.long 0x8f600
+		.long 0x5ac200ff
+		.long 0x8ff00
+		.long 0x5ae200ff
+		.long 0xc0000
+		.long 0x620000ff
+		.long 0xc0800
+		.long 0x622000ff
+		.long 0xc1000
+		.long 0x624000ff
+		.long 0xc1800
+		.long 0x626100ff
+		.long 0xc2000
+		.long 0x628100ff
+		.long 0xc2900
+		.long 0x62a100ff
+		.long 0xc3100
+		.long 0x62c200ff
+		.long 0xc3900
+		.long 0x62e200ff
+		.long 0xc4100
+		.long 0x6a0000ff
+		.long 0xc4a00
+		.long 0x6a2000ff
+		.long 0xc5200
+		.long 0x6a4000ff
+		.long 0xc5a00
+		.long 0x6a6100ff
+		.long 0xc6200
+		.long 0x6a8100ff
+		.long 0xc6a00
+		.long 0x6aa100ff
+		.long 0xc7300
+		.long 0x6ac200ff
+		.long 0xc7b00
+		.long 0x6ae200ff
+		.long 0xc8300
+		.long 0x730000ff
+		.long 0xc8b00
+		.long 0x732000ff
+		.long 0xc9400
+		.long 0x734000ff
+		.long 0xc9c00
+		.long 0x736100ff
+		.long 0xca400
+		.long 0x738100ff
+		.long 0xcac00
+		.long 0x73a100ff
+		.long 0xcb400
+		.long 0x73c200ff
+		.long 0xcbd00
+		.long 0x73e200ff
+		.long 0xcc500
+		.long 0x7b0000ff
+		.long 0xccd00
+		.long 0x7b2000ff
+		.long 0xcd500
+		.long 0x7b4000ff
+		.long 0xcde00
+		.long 0x7b6100ff
+		.long 0xce600
+		.long 0x7b8100ff
+		.long 0xcee00
+		.long 0x7ba100ff
+		.long 0xcf600
+		.long 0x7bc200ff
+		.long 0xcff00
+		.long 0x7be200ff
+		.long 0x100000
+		.long 0x830000ff
+		.long 0x100800
+		.long 0x832000ff
+		.long 0x101000
+		.long 0x834000ff
+		.long 0x101800
+		.long 0x836100ff
+		.long 0x102000
+		.long 0x838100ff
+		.long 0x102900
+		.long 0x83a100ff
+		.long 0x103100
+		.long 0x83c200ff
+		.long 0x103900
+		.long 0x83e200ff
+		.long 0x104100
+		.long 0x8b0000ff
+		.long 0x104a00
+		.long 0x8b2000ff
+		.long 0x105200
+		.long 0x8b4000ff
+		.long 0x105a00
+		.long 0x8b6100ff
+		.long 0x106200
+		.long 0x8b8100ff
+		.long 0x106a00
+		.long 0x8ba100ff
+		.long 0x107300
+		.long 0x8bc200ff
+		.long 0x107b00
+		.long 0x8be200ff
+		.long 0x108300
+		.long 0x940000ff
+		.long 0x108b00
+		.long 0x942000ff
+		.long 0x109400
+		.long 0x944000ff
+		.long 0x109c00
+		.long 0x946100ff
+		.long 0x10a400
+		.long 0x948100ff
+		.long 0x10ac00
+		.long 0x94a100ff
+		.long 0x10b400
+		.long 0x94c200ff
+		.long 0x10bd00
+		.long 0x94e200ff
+		.long 0x10c500
+		.long 0x9c0000ff
+		.long 0x10cd00
+		.long 0x9c2000ff
+		.long 0x10d500
+		.long 0x9c4000ff
+		.long 0x10de00
+		.long 0x9c6100ff
+		.long 0x10e600
+		.long 0x9c8100ff
+		.long 0x10ee00
+		.long 0x9ca100ff
+		.long 0x10f600
+		.long 0x9cc200ff
+		.long 0x10ff00
+		.long 0x9ce200ff
+		.long 0x140000
+		.long 0xa40000ff
+		.long 0x140800
+		.long 0xa42000ff
+		.long 0x141000
+		.long 0xa44000ff
+		.long 0x141800
+		.long 0xa46100ff
+		.long 0x142000
+		.long 0xa48100ff
+		.long 0x142900
+		.long 0xa4a100ff
+		.long 0x143100
+		.long 0xa4c200ff
+		.long 0x143900
+		.long 0xa4e200ff
+		.long 0x144100
+		.long 0xac0000ff
+		.long 0x144a00
+		.long 0xac2000ff
+		.long 0x145200
+		.long 0xac4000ff
+		.long 0x145a00
+		.long 0xac6100ff
+		.long 0x146200
+		.long 0xac8100ff
+		.long 0x146a00
+		.long 0xaca100ff
+		.long 0x147300
+		.long 0xacc200ff
+		.long 0x147b00
+		.long 0xace200ff
+		.long 0x148300
+		.long 0xb40000ff
+		.long 0x148b00
+		.long 0xb42000ff
+		.long 0x149400
+		.long 0xb44000ff
+		.long 0x149c00
+		.long 0xb46100ff
+		.long 0x14a400
+		.long 0xb48100ff
+		.long 0x14ac00
+		.long 0xb4a100ff
+		.long 0x14b400
+		.long 0xb4c200ff
+		.long 0x14bd00
+		.long 0xb4e200ff
+		.long 0x14c500
+		.long 0xbd0000ff
+		.long 0x14cd00
+		.long 0xbd2000ff
+		.long 0x14d500
+		.long 0xbd4000ff
+		.long 0x14de00
+		.long 0xbd6100ff
+		.long 0x14e600
+		.long 0xbd8100ff
+		.long 0x14ee00
+		.long 0xbda100ff
+		.long 0x14f600
+		.long 0xbdc200ff
+		.long 0x14ff00
+		.long 0xbde200ff
+		.long 0x180000
+		.long 0xc50000ff
+		.long 0x180800
+		.long 0xc52000ff
+		.long 0x181000
+		.long 0xc54000ff
+		.long 0x181800
+		.long 0xc56100ff
+		.long 0x182000
+		.long 0xc58100ff
+		.long 0x182900
+		.long 0xc5a100ff
+		.long 0x183100
+		.long 0xc5c200ff
+		.long 0x183900
+		.long 0xc5e200ff
+		.long 0x184100
+		.long 0xcd0000ff
+		.long 0x184a00
+		.long 0xcd2000ff
+		.long 0x185200
+		.long 0xcd4000ff
+		.long 0x185a00
+		.long 0xcd6100ff
+		.long 0x186200
+		.long 0xcd8100ff
+		.long 0x186a00
+		.long 0xcda100ff
+		.long 0x187300
+		.long 0xcdc200ff
+		.long 0x187b00
+		.long 0xcde200ff
+		.long 0x188300
+		.long 0xd50000ff
+		.long 0x188b00
+		.long 0xd52000ff
+		.long 0x189400
+		.long 0xd54000ff
+		.long 0x189c00
+		.long 0xd56100ff
+		.long 0x18a400
+		.long 0xd58100ff
+		.long 0x18ac00
+		.long 0xd5a100ff
+		.long 0x18b400
+		.long 0xd5c200ff
+		.long 0x18bd00
+		.long 0xd5e200ff
+		.long 0x18c500
+		.long 0xde0000ff
+		.long 0x18cd00
+		.long 0xde2000ff
+		.long 0x18d500
+		.long 0xde4000ff
+		.long 0x18de00
+		.long 0xde6100ff
+		.long 0x18e600
+		.long 0xde8100ff
+		.long 0x18ee00
+		.long 0xdea100ff
+		.long 0x18f600
+		.long 0xdec200ff
+		.long 0x18ff00
+		.long 0xdee200ff
+		.long 0x1c0000
+		.long 0xe60000ff
+		.long 0x1c0800
+		.long 0xe62000ff
+		.long 0x1c1000
+		.long 0xe64000ff
+		.long 0x1c1800
+		.long 0xe66100ff
+		.long 0x1c2000
+		.long 0xe68100ff
+		.long 0x1c2900
+		.long 0xe6a100ff
+		.long 0x1c3100
+		.long 0xe6c200ff
+		.long 0x1c3900
+		.long 0xe6e200ff
+		.long 0x1c4100
+		.long 0xee0000ff
+		.long 0x1c4a00
+		.long 0xee2000ff
+		.long 0x1c5200
+		.long 0xee4000ff
+		.long 0x1c5a00
+		.long 0xee6100ff
+		.long 0x1c6200
+		.long 0xee8100ff
+		.long 0x1c6a00
+		.long 0xeea100ff
+		.long 0x1c7300
+		.long 0xeec200ff
+		.long 0x1c7b00
+		.long 0xeee200ff
+		.long 0x1c8300
+		.long 0xf60000ff
+		.long 0x1c8b00
+		.long 0xf62000ff
+		.long 0x1c9400
+		.long 0xf64000ff
+		.long 0x1c9c00
+		.long 0xf66100ff
+		.long 0x1ca400
+		.long 0xf68100ff
+		.long 0x1cac00
+		.long 0xf6a100ff
+		.long 0x1cb400
+		.long 0xf6c200ff
+		.long 0x1cbd00
+		.long 0xf6e200ff
+		.long 0x1cc500
+		.long 0xff0000ff
+		.long 0x1ccd00
+		.long 0xff2000ff
+		.long 0x1cd500
+		.long 0xff4000ff
+		.long 0x1cde00
+		.long 0xff6100ff
+		.long 0x1ce600
+		.long 0xff8100ff
+		.long 0x1cee00
+		.long 0xffa100ff
+		.long 0x1cf600
+		.long 0xffc200ff
+		.long 0x1cff00
+		.long 0xffe200ff
+
+_ConvertX86p16_32BGRA888_LUT_X86:
+		.long 0x00000
+		.long 0x000ff
+		.long 0x8000000
+		.long 0x2000ff
+		.long 0x10000000
+		.long 0x4000ff
+		.long 0x18000000
+		.long 0x6100ff
+		.long 0x20000000
+		.long 0x8100ff
+		.long 0x29000000
+		.long 0xa100ff
+		.long 0x31000000
+		.long 0xc200ff
+		.long 0x39000000
+		.long 0xe200ff
+		.long 0x41000000
+		.long 0x008ff
+		.long 0x4a000000
+		.long 0x2008ff
+		.long 0x52000000
+		.long 0x4008ff
+		.long 0x5a000000
+		.long 0x6108ff
+		.long 0x62000000
+		.long 0x8108ff
+		.long 0x6a000000
+		.long 0xa108ff
+		.long 0x73000000
+		.long 0xc208ff
+		.long 0x7b000000
+		.long 0xe208ff
+		.long 0x83000000
+		.long 0x010ff
+		.long 0x8b000000
+		.long 0x2010ff
+		.long 0x94000000
+		.long 0x4010ff
+		.long 0x9c000000
+		.long 0x6110ff
+		.long 0xa4000000
+		.long 0x8110ff
+		.long 0xac000000
+		.long 0xa110ff
+		.long 0xb4000000
+		.long 0xc210ff
+		.long 0xbd000000
+		.long 0xe210ff
+		.long 0xc5000000
+		.long 0x018ff
+		.long 0xcd000000
+		.long 0x2018ff
+		.long 0xd5000000
+		.long 0x4018ff
+		.long 0xde000000
+		.long 0x6118ff
+		.long 0xe6000000
+		.long 0x8118ff
+		.long 0xee000000
+		.long 0xa118ff
+		.long 0xf6000000
+		.long 0xc218ff
+		.long 0xff000000
+		.long 0xe218ff
+		.long 0x40000
+		.long 0x020ff
+		.long 0x8040000
+		.long 0x2020ff
+		.long 0x10040000
+		.long 0x4020ff
+		.long 0x18040000
+		.long 0x6120ff
+		.long 0x20040000
+		.long 0x8120ff
+		.long 0x29040000
+		.long 0xa120ff
+		.long 0x31040000
+		.long 0xc220ff
+		.long 0x39040000
+		.long 0xe220ff
+		.long 0x41040000
+		.long 0x029ff
+		.long 0x4a040000
+		.long 0x2029ff
+		.long 0x52040000
+		.long 0x4029ff
+		.long 0x5a040000
+		.long 0x6129ff
+		.long 0x62040000
+		.long 0x8129ff
+		.long 0x6a040000
+		.long 0xa129ff
+		.long 0x73040000
+		.long 0xc229ff
+		.long 0x7b040000
+		.long 0xe229ff
+		.long 0x83040000
+		.long 0x031ff
+		.long 0x8b040000
+		.long 0x2031ff
+		.long 0x94040000
+		.long 0x4031ff
+		.long 0x9c040000
+		.long 0x6131ff
+		.long 0xa4040000
+		.long 0x8131ff
+		.long 0xac040000
+		.long 0xa131ff
+		.long 0xb4040000
+		.long 0xc231ff
+		.long 0xbd040000
+		.long 0xe231ff
+		.long 0xc5040000
+		.long 0x039ff
+		.long 0xcd040000
+		.long 0x2039ff
+		.long 0xd5040000
+		.long 0x4039ff
+		.long 0xde040000
+		.long 0x6139ff
+		.long 0xe6040000
+		.long 0x8139ff
+		.long 0xee040000
+		.long 0xa139ff
+		.long 0xf6040000
+		.long 0xc239ff
+		.long 0xff040000
+		.long 0xe239ff
+		.long 0x80000
+		.long 0x041ff
+		.long 0x8080000
+		.long 0x2041ff
+		.long 0x10080000
+		.long 0x4041ff
+		.long 0x18080000
+		.long 0x6141ff
+		.long 0x20080000
+		.long 0x8141ff
+		.long 0x29080000
+		.long 0xa141ff
+		.long 0x31080000
+		.long 0xc241ff
+		.long 0x39080000
+		.long 0xe241ff
+		.long 0x41080000
+		.long 0x04aff
+		.long 0x4a080000
+		.long 0x204aff
+		.long 0x52080000
+		.long 0x404aff
+		.long 0x5a080000
+		.long 0x614aff
+		.long 0x62080000
+		.long 0x814aff
+		.long 0x6a080000
+		.long 0xa14aff
+		.long 0x73080000
+		.long 0xc24aff
+		.long 0x7b080000
+		.long 0xe24aff
+		.long 0x83080000
+		.long 0x052ff
+		.long 0x8b080000
+		.long 0x2052ff
+		.long 0x94080000
+		.long 0x4052ff
+		.long 0x9c080000
+		.long 0x6152ff
+		.long 0xa4080000
+		.long 0x8152ff
+		.long 0xac080000
+		.long 0xa152ff
+		.long 0xb4080000
+		.long 0xc252ff
+		.long 0xbd080000
+		.long 0xe252ff
+		.long 0xc5080000
+		.long 0x05aff
+		.long 0xcd080000
+		.long 0x205aff
+		.long 0xd5080000
+		.long 0x405aff
+		.long 0xde080000
+		.long 0x615aff
+		.long 0xe6080000
+		.long 0x815aff
+		.long 0xee080000
+		.long 0xa15aff
+		.long 0xf6080000
+		.long 0xc25aff
+		.long 0xff080000
+		.long 0xe25aff
+		.long 0xc0000
+		.long 0x062ff
+		.long 0x80c0000
+		.long 0x2062ff
+		.long 0x100c0000
+		.long 0x4062ff
+		.long 0x180c0000
+		.long 0x6162ff
+		.long 0x200c0000
+		.long 0x8162ff
+		.long 0x290c0000
+		.long 0xa162ff
+		.long 0x310c0000
+		.long 0xc262ff
+		.long 0x390c0000
+		.long 0xe262ff
+		.long 0x410c0000
+		.long 0x06aff
+		.long 0x4a0c0000
+		.long 0x206aff
+		.long 0x520c0000
+		.long 0x406aff
+		.long 0x5a0c0000
+		.long 0x616aff
+		.long 0x620c0000
+		.long 0x816aff
+		.long 0x6a0c0000
+		.long 0xa16aff
+		.long 0x730c0000
+		.long 0xc26aff
+		.long 0x7b0c0000
+		.long 0xe26aff
+		.long 0x830c0000
+		.long 0x073ff
+		.long 0x8b0c0000
+		.long 0x2073ff
+		.long 0x940c0000
+		.long 0x4073ff
+		.long 0x9c0c0000
+		.long 0x6173ff
+		.long 0xa40c0000
+		.long 0x8173ff
+		.long 0xac0c0000
+		.long 0xa173ff
+		.long 0xb40c0000
+		.long 0xc273ff
+		.long 0xbd0c0000
+		.long 0xe273ff
+		.long 0xc50c0000
+		.long 0x07bff
+		.long 0xcd0c0000
+		.long 0x207bff
+		.long 0xd50c0000
+		.long 0x407bff
+		.long 0xde0c0000
+		.long 0x617bff
+		.long 0xe60c0000
+		.long 0x817bff
+		.long 0xee0c0000
+		.long 0xa17bff
+		.long 0xf60c0000
+		.long 0xc27bff
+		.long 0xff0c0000
+		.long 0xe27bff
+		.long 0x100000
+		.long 0x083ff
+		.long 0x8100000
+		.long 0x2083ff
+		.long 0x10100000
+		.long 0x4083ff
+		.long 0x18100000
+		.long 0x6183ff
+		.long 0x20100000
+		.long 0x8183ff
+		.long 0x29100000
+		.long 0xa183ff
+		.long 0x31100000
+		.long 0xc283ff
+		.long 0x39100000
+		.long 0xe283ff
+		.long 0x41100000
+		.long 0x08bff
+		.long 0x4a100000
+		.long 0x208bff
+		.long 0x52100000
+		.long 0x408bff
+		.long 0x5a100000
+		.long 0x618bff
+		.long 0x62100000
+		.long 0x818bff
+		.long 0x6a100000
+		.long 0xa18bff
+		.long 0x73100000
+		.long 0xc28bff
+		.long 0x7b100000
+		.long 0xe28bff
+		.long 0x83100000
+		.long 0x094ff
+		.long 0x8b100000
+		.long 0x2094ff
+		.long 0x94100000
+		.long 0x4094ff
+		.long 0x9c100000
+		.long 0x6194ff
+		.long 0xa4100000
+		.long 0x8194ff
+		.long 0xac100000
+		.long 0xa194ff
+		.long 0xb4100000
+		.long 0xc294ff
+		.long 0xbd100000
+		.long 0xe294ff
+		.long 0xc5100000
+		.long 0x09cff
+		.long 0xcd100000
+		.long 0x209cff
+		.long 0xd5100000
+		.long 0x409cff
+		.long 0xde100000
+		.long 0x619cff
+		.long 0xe6100000
+		.long 0x819cff
+		.long 0xee100000
+		.long 0xa19cff
+		.long 0xf6100000
+		.long 0xc29cff
+		.long 0xff100000
+		.long 0xe29cff
+		.long 0x140000
+		.long 0x0a4ff
+		.long 0x8140000
+		.long 0x20a4ff
+		.long 0x10140000
+		.long 0x40a4ff
+		.long 0x18140000
+		.long 0x61a4ff
+		.long 0x20140000
+		.long 0x81a4ff
+		.long 0x29140000
+		.long 0xa1a4ff
+		.long 0x31140000
+		.long 0xc2a4ff
+		.long 0x39140000
+		.long 0xe2a4ff
+		.long 0x41140000
+		.long 0x0acff
+		.long 0x4a140000
+		.long 0x20acff
+		.long 0x52140000
+		.long 0x40acff
+		.long 0x5a140000
+		.long 0x61acff
+		.long 0x62140000
+		.long 0x81acff
+		.long 0x6a140000
+		.long 0xa1acff
+		.long 0x73140000
+		.long 0xc2acff
+		.long 0x7b140000
+		.long 0xe2acff
+		.long 0x83140000
+		.long 0x0b4ff
+		.long 0x8b140000
+		.long 0x20b4ff
+		.long 0x94140000
+		.long 0x40b4ff
+		.long 0x9c140000
+		.long 0x61b4ff
+		.long 0xa4140000
+		.long 0x81b4ff
+		.long 0xac140000
+		.long 0xa1b4ff
+		.long 0xb4140000
+		.long 0xc2b4ff
+		.long 0xbd140000
+		.long 0xe2b4ff
+		.long 0xc5140000
+		.long 0x0bdff
+		.long 0xcd140000
+		.long 0x20bdff
+		.long 0xd5140000
+		.long 0x40bdff
+		.long 0xde140000
+		.long 0x61bdff
+		.long 0xe6140000
+		.long 0x81bdff
+		.long 0xee140000
+		.long 0xa1bdff
+		.long 0xf6140000
+		.long 0xc2bdff
+		.long 0xff140000
+		.long 0xe2bdff
+		.long 0x180000
+		.long 0x0c5ff
+		.long 0x8180000
+		.long 0x20c5ff
+		.long 0x10180000
+		.long 0x40c5ff
+		.long 0x18180000
+		.long 0x61c5ff
+		.long 0x20180000
+		.long 0x81c5ff
+		.long 0x29180000
+		.long 0xa1c5ff
+		.long 0x31180000
+		.long 0xc2c5ff
+		.long 0x39180000
+		.long 0xe2c5ff
+		.long 0x41180000
+		.long 0x0cdff
+		.long 0x4a180000
+		.long 0x20cdff
+		.long 0x52180000
+		.long 0x40cdff
+		.long 0x5a180000
+		.long 0x61cdff
+		.long 0x62180000
+		.long 0x81cdff
+		.long 0x6a180000
+		.long 0xa1cdff
+		.long 0x73180000
+		.long 0xc2cdff
+		.long 0x7b180000
+		.long 0xe2cdff
+		.long 0x83180000
+		.long 0x0d5ff
+		.long 0x8b180000
+		.long 0x20d5ff
+		.long 0x94180000
+		.long 0x40d5ff
+		.long 0x9c180000
+		.long 0x61d5ff
+		.long 0xa4180000
+		.long 0x81d5ff
+		.long 0xac180000
+		.long 0xa1d5ff
+		.long 0xb4180000
+		.long 0xc2d5ff
+		.long 0xbd180000
+		.long 0xe2d5ff
+		.long 0xc5180000
+		.long 0x0deff
+		.long 0xcd180000
+		.long 0x20deff
+		.long 0xd5180000
+		.long 0x40deff
+		.long 0xde180000
+		.long 0x61deff
+		.long 0xe6180000
+		.long 0x81deff
+		.long 0xee180000
+		.long 0xa1deff
+		.long 0xf6180000
+		.long 0xc2deff
+		.long 0xff180000
+		.long 0xe2deff
+		.long 0x1c0000
+		.long 0x0e6ff
+		.long 0x81c0000
+		.long 0x20e6ff
+		.long 0x101c0000
+		.long 0x40e6ff
+		.long 0x181c0000
+		.long 0x61e6ff
+		.long 0x201c0000
+		.long 0x81e6ff
+		.long 0x291c0000
+		.long 0xa1e6ff
+		.long 0x311c0000
+		.long 0xc2e6ff
+		.long 0x391c0000
+		.long 0xe2e6ff
+		.long 0x411c0000
+		.long 0x0eeff
+		.long 0x4a1c0000
+		.long 0x20eeff
+		.long 0x521c0000
+		.long 0x40eeff
+		.long 0x5a1c0000
+		.long 0x61eeff
+		.long 0x621c0000
+		.long 0x81eeff
+		.long 0x6a1c0000
+		.long 0xa1eeff
+		.long 0x731c0000
+		.long 0xc2eeff
+		.long 0x7b1c0000
+		.long 0xe2eeff
+		.long 0x831c0000
+		.long 0x0f6ff
+		.long 0x8b1c0000
+		.long 0x20f6ff
+		.long 0x941c0000
+		.long 0x40f6ff
+		.long 0x9c1c0000
+		.long 0x61f6ff
+		.long 0xa41c0000
+		.long 0x81f6ff
+		.long 0xac1c0000
+		.long 0xa1f6ff
+		.long 0xb41c0000
+		.long 0xc2f6ff
+		.long 0xbd1c0000
+		.long 0xe2f6ff
+		.long 0xc51c0000
+		.long 0x0ffff
+		.long 0xcd1c0000
+		.long 0x20ffff
+		.long 0xd51c0000
+		.long 0x40ffff
+		.long 0xde1c0000
+		.long 0x61ffff
+		.long 0xe61c0000
+		.long 0x81ffff
+		.long 0xee1c0000
+		.long 0xa1ffff
+		.long 0xf61c0000
+		.long 0xc2ffff
+		.long 0xff1c0000
+		.long 0xe2ffff
+

+ 297 - 0
packages/hermes/src/i386/x86_clr.as

@@ -0,0 +1,297 @@
+#
+# x86 surface clear routines for HERMES
+# Copyright (c) 1998 Christian Nentwich ([email protected])
+# This source code is licensed under the GNU LGPL
+# 
+# Please refer to the file COPYING.LIB contained in the distribution for
+# licensing conditions
+#
+# (04/10/99)    Modified ClearX86_8             <[email protected]>
+
+
+
+
+.globl _ClearX86_32
+.globl _ClearX86_24
+.globl _ClearX86_16
+.globl _ClearX86_8
+
+.text
+
+##   
+## --------------------------------------------------------------------------
+## HermesClearInterface (ebp+..)
+##   0: char8 *dest
+##   4: int32 value
+##   8: unsigned int width (already checked to be >0!)
+##  12: unsigned int height (already checked to be >0!)
+##  16: int add
+
+.align 8
+_ClearX86_32: 
+        pushl %ebp
+        movl %esp,%ebp
+
+        movl 8(%ebp),%ebp
+
+        movl (%ebp),%edi        # destination
+        movl 4(%ebp),%eax       # pixel value   
+
+        movl 12(%ebp),%edx      # height
+.align 4
+_ClearX86_32.L_y: 
+        movl 8(%ebp),%ecx
+        rep
+ stosl
+
+        addl 16(%ebp),%edi
+
+        decl %edx
+        jnz _ClearX86_32.L_y
+
+        popl %ebp
+        ret
+
+
+
+_ClearX86_24: 
+        ret
+
+
+
+.align 8
+_ClearX86_16: 
+        pushl %ebp
+        movl %esp,%ebp
+
+        movl 8(%ebp),%ebp
+
+        movl (%ebp),%edi        # destination
+        movl 4(%ebp),%eax       # pixel value   
+
+        movl 12(%ebp),%edx      # height
+        movl %eax,%ebx
+
+        shll $16,%eax           # Duplicate pixel value
+        andl $0x0ffff,%ebx
+
+        orl %ebx,%eax
+_ClearX86_16.L_y: 
+        movl 8(%ebp),%ecx
+
+        testl $3,%edi           # Check if destination is aligned mod 4
+        jz _ClearX86_16.L_aligned
+
+        movw %ax,(%edi)         # otherwise write one pixel
+        addl $2,%edi
+
+        decl %ecx
+        jz _ClearX86_16.L_endline
+
+_ClearX86_16.L_aligned: 
+        shrl %ecx
+
+rep
+ stosl
+
+        jnc _ClearX86_16.L_endline
+
+        movw %ax,(%edi)
+        addl $2,%edi
+
+_ClearX86_16.L_endline: 
+        addl 16(%ebp),%edi
+
+        decl %edx
+        jnz _ClearX86_16.L_y
+
+        popl %ebp
+        ret
+
+
+
+.align 8
+_ClearX86_8: 
+        pushl %ebp
+        movl %esp,%ebp
+
+        movl 8(%ebp),%ebp
+
+        movl 4(%ebp),%eax       # pixel value           
+        movl 12(%ebp),%edx      # height
+
+        movb %al,%ah
+        movl (%ebp),%edi        # destination
+
+        movl %eax,%ecx
+
+        shll $16,%eax           # Put the byte pixel value in all four bytes
+        andl $0x0ffff,%ecx      # of eax
+
+        movl 8(%ebp),%ebx
+        orl %ecx,%eax
+
+        cmpl $5,%ebx            # removes need for extra checks later
+        jbe _ClearX86_8.L_short_y
+
+.align 4
+_ClearX86_8.L_y: 
+        testl $3,%edi
+        jz _ClearX86_8.L_aligned
+
+        movl %edi,%ecx
+        negl %ecx
+        andl $3,%ecx
+
+        subl %ecx,%ebx
+
+        rep
+ stosb
+
+_ClearX86_8.L_aligned: 
+        movl %ebx,%ecx
+
+        shrl $2,%ecx
+        andl $3,%ebx
+
+        rep
+ stosl
+
+        movl %ebx,%ecx
+        rep
+ stosb
+
+        addl 16(%ebp),%edi
+
+        decl %edx
+        movl 8(%ebp),%ebx
+        jnz _ClearX86_8.L_y
+
+        popl %ebp
+        ret
+
+## Short loop
+.align 4
+_ClearX86_8.L_short_y: 
+        movl %ebx,%ecx
+
+        rep
+ stosb
+        addl 16(%ebp),%edi
+
+        decl %edx
+        jnz _ClearX86_8.L_short_y
+
+        popl %ebp
+        ret
+
+## ClearX86_8 version 2,  
+## Im not sure wheather this is faster or not... 
+## too many jumps could confuse the CPU branch quessing
+
+
+.align 8
+_ClearX86_8_2: 
+        pushl %ebp
+        movl %esp,%ebp
+
+        movl 8(%ebp),%ebp
+
+        movl 4(%ebp),%eax       # pixel value           
+        movl 12(%ebp),%edx      # height
+
+        movb %al,%ah
+        movl (%ebp),%edi        # destination
+
+        movl %eax,%ecx
+
+        shll $16,%eax           # Put the byte pixel value in all four bytes
+        andl $0x0ffff,%ecx      # of eax
+
+        movl 8(%ebp),%ebx
+        orl %ecx,%eax
+
+        cmpl $5,%ebx            # removes need for extra checks in main loop
+        jbe _ClearX86_8_2.L_short_y
+
+
+.align 4
+_ClearX86_8_2.L_y: 
+        testl $3,%edi
+        jz _ClearX86_8_2.L_aligned
+
+        movl %edi,%ecx
+        negl %ecx
+        andl $3,%ecx
+
+        movb %al,(%edi)
+        subl %ecx,%ebx
+
+        incl %edi
+
+        decl %ecx
+        jz _ClearX86_8_2.L_aligned
+
+        movb %al,(%edi)
+        incl %edi
+        decl %ecx
+        jz _ClearX86_8_2.L_aligned
+
+        movb %al,(%edi)
+        incl %edi
+
+_ClearX86_8_2.L_aligned: 
+        movl %ebx,%ecx
+
+        shrl $2,%ecx
+        andl $3,%ebx
+
+        rep
+ stosl
+
+        jz _ClearX86_8_2.L_endline
+                # ebx
+
+        movb %al,(%edi)
+                # Write remaining (1,2 or 3) pixels
+        incl %edi
+        decl %ebx
+        jz _ClearX86_8_2.L_endline
+
+        movb %al,(%edi)
+        incl %edi
+        decl %ebx
+        jz _ClearX86_8_2.L_endline
+
+        movb %al,(%edi)
+        incl %edi
+        decl %ebx
+        jz _ClearX86_8_2.L_endline
+
+        movb %al,(%edi)
+        incl %edi
+
+_ClearX86_8_2.L_endline: 
+        addl 16(%ebp),%edi
+
+        decl %edx
+        movl 8(%ebp),%ebx
+        jnz _ClearX86_8_2.L_y
+
+        popl %ebp
+        ret
+
+## Short loop
+.align 4
+_ClearX86_8_2.L_short_y: 
+        movl %ebx,%ecx
+
+        rep
+ stosb
+        addl 16(%ebp),%edi
+
+        decl %edx
+        jnz _ClearX86_8_2.L_short_y
+
+        popl %ebp
+        ret

+ 182 - 0
packages/hermes/src/i386/x86_main.as

@@ -0,0 +1,182 @@
+#
+# x86 format converters for HERMES
+# Some routines Copyright (c) 1998 Christian Nentwich ([email protected])
+# This source code is licensed under the GNU LGPL
+# 
+# Please refer to the file COPYING.LIB contained in the distribution for
+# licensing conditions          
+#
+
+
+
+.globl _ConvertX86
+.globl _ConvertX86Stretch
+.globl _x86return
+.globl _x86return_S
+
+.globl _Hermes_X86_CPU
+
+
+.data
+
+cpu_flags: .long 0
+
+.text
+
+.equ s_pixels, 0
+.equ s_width, 4
+.equ s_height, 8
+.equ s_add, 12
+.equ d_pixels, 16
+.equ d_width, 20
+.equ d_height, 24
+.equ d_add, 28
+.equ conv_func, 32
+.equ lookup, 36
+.equ s_pitch, 40
+.equ d_pitch, 44
+
+## _ConvertX86:  
+## [ESP+8] ConverterInfo*
+## --------------------------------------------------------------------------
+##
+## ConvertX86Stretch 'abuses' the following info structure fields:
+##      - d_pitch for the y increment
+##      - s_add for the x increment
+## because they're unused anyway and this is thread safe.. (it's a per
+## converter handle structure)
+_ConvertX86Stretch: 
+        pushl %ebp
+        movl %esp,%ebp
+
+        movl 8(%ebp),%ebp
+
+        movl s_height(%ebp),%eax
+        sall $16,%eax
+        cdq
+        idivl d_height(%ebp)
+        movl %eax,d_pitch(%ebp)
+
+        movl s_width(%ebp),%eax
+        sall $16,%eax
+        cdq
+        idivl d_width(%ebp)
+        movl %eax,s_add(%ebp)
+
+        movl $0,s_height(%ebp)
+
+        movl d_pixels(%ebp),%edi
+        movl s_pixels(%ebp),%esi
+
+        movl s_add(%ebp),%edx
+        movl d_width(%ebp),%ecx
+        jmp *conv_func(%ebp)
+
+.align 8
+_x86return_S: 
+
+        decl d_height(%ebp)
+        jz endconvert_S
+
+        movl s_height(%ebp),%eax
+        addl d_add(%ebp),%edi
+
+        addl d_pitch(%ebp),%eax
+
+        movl %eax,%ebx
+
+        shrl $16,%eax
+
+        mull s_pitch(%ebp)
+        andl $0x0ffff,%ebx
+
+        movl %ebx,s_height(%ebp)
+        addl %eax,%esi
+
+        movl s_add(%ebp),%edx
+        movl d_width(%ebp),%ecx
+
+        jmp *conv_func(%ebp)
+
+endconvert_S: 
+
+        popl %ebp
+        ret
+
+
+
+_ConvertX86: 
+        pushl %ebp
+        movl %esp,%ebp
+
+        movl 8(%ebp),%ebp
+
+        movl s_pixels(%ebp),%esi
+        movl d_width(%ebp),%ecx
+        movl d_pixels(%ebp),%edi
+
+        jmp *32(%ebp)
+
+.align 8
+_x86return: 
+        decl s_height(%ebp)
+        jz endconvert
+
+        movl d_width(%ebp),%ecx
+        addl s_add(%ebp),%esi
+        addl d_add(%ebp),%edi
+
+        jmp *32(%ebp)
+
+
+endconvert: 
+        popl %ebp
+        ret
+
+
+
+## Hermes_X86_CPU returns the CPUID flags in eax
+
+_Hermes_X86_CPU: 
+        pushfl
+        popl %eax
+
+        movl %eax,%ecx
+
+        xorl $0x040000,%eax
+        pushl %eax
+
+        popfl
+        pushfl
+
+        popl %eax
+        xorl %ecx,%eax
+        jz _Hermes_X86_CPU.L1   # Processor is 386
+
+        pushl %ecx
+        popfl
+
+        movl %ecx,%eax
+        xorl $0x200000,%eax
+
+        pushl %eax
+        popfl
+        pushfl
+
+        popl %eax
+        xorl %ecx,%eax
+        je _Hermes_X86_CPU.L1
+
+        pusha
+
+        movl $1,%eax
+        cpuid
+
+        movl %edx,cpu_flags
+
+        popa
+
+        movl cpu_flags,%eax
+
+_Hermes_X86_CPU.L1: 
+        ret

+ 1154 - 0
packages/hermes/src/i386/x86p_16.as

@@ -0,0 +1,1154 @@
+#
+# x86 format converters for HERMES
+# Copyright (c) 1998 Glenn Fielder ([email protected])
+# This source code is licensed under the GNU LGPL
+# 
+# Please refer to the file COPYING.LIB contained in the distribution for
+# licensing conditions          
+# 
+# Routines adjusted for Hermes by Christian Nentwich ([email protected])
+# Used with permission.
+# 
+
+
+#BITS 32
+
+.globl _ConvertX86p16_32RGB888
+.globl _ConvertX86p16_32BGR888
+.globl _ConvertX86p16_32RGBA888
+.globl _ConvertX86p16_32BGRA888
+.globl _ConvertX86p16_24RGB888
+.globl _ConvertX86p16_24BGR888
+.globl _ConvertX86p16_16BGR565
+.globl _ConvertX86p16_16RGB555
+.globl _ConvertX86p16_16BGR555
+.globl _ConvertX86p16_8RGB332
+
+.extern _ConvertX86
+.extern _x86return
+
+.globl _ConvertX86p16_32RGB888_LUT_X86
+.globl _ConvertX86p16_32BGR888_LUT_X86
+.globl _ConvertX86p16_32RGBA888_LUT_X86
+.globl _ConvertX86p16_32BGRA888_LUT_X86
+
+.include "src/i386/x8616lut.as"
+
+.text
+
+
+
+_ConvertX86p16_32RGB888: 
+
+    # check short
+    cmpl $32,%ecx
+    ja _ConvertX86p16_32RGB888.L3
+
+
+    # short loop
+    xorl %ebx,%ebx
+_ConvertX86p16_32RGB888.L1: movb (%esi),%bl             # ebx = lower byte pixel 1
+    movl _ConvertX86p16_32RGB888_LUT_X86(,%ebx,8),%eax  # eax = ARGB8888 of lower byte pixel 1
+    movb 1(%esi),%bl                                    # ebx = upper byte pixel 1
+    movl _ConvertX86p16_32RGB888_LUT_X86+4(,%ebx,8),%edx# edx = ARGB8888 of upper byte pixel 1
+    addl %edx,%eax
+    movl %eax,(%edi)
+    addl $2,%esi
+    addl $4,%edi
+    decl %ecx
+    jnz _ConvertX86p16_32RGB888.L1
+_ConvertX86p16_32RGB888.L2: 
+    jmp _x86return
+
+
+_ConvertX86p16_32RGB888.L3:  # save ebp
+    pushl %ebp
+
+    # save count
+    pushl %ecx
+
+    # unroll twice
+    movl %ecx,%ebp
+    shrl %ebp
+
+    # point arrays to end
+    leal (%esi,%ebp,4),%esi
+    leal (%edi,%ebp,8),%edi
+
+    # negative counter 
+    negl %ebp
+
+    # clear
+    xorl %ebx,%ebx
+    xorl %ecx,%ecx
+
+    # prestep
+    movb (%esi,%ebp,4),%cl
+    movb 1(%esi,%ebp,4),%bl
+
+_ConvertX86p16_32RGB888.L4: movl _ConvertX86p16_32RGB888_LUT_X86(,%ecx,8),%edx
+        movb 2(%esi,%ebp,4),%cl
+
+        movl _ConvertX86p16_32RGB888_LUT_X86+4(,%ebx,8),%eax
+        movb 3(%esi,%ebp,4),%bl
+
+        addl %edx,%eax
+        movl _ConvertX86p16_32RGB888_LUT_X86(,%ecx,8),%edx
+
+        movl %eax,(%edi,%ebp,8)
+        movl _ConvertX86p16_32RGB888_LUT_X86+4(,%ebx,8),%eax
+
+        addl %edx,%eax
+        movb 4(%esi,%ebp,4),%cl
+
+        movl %eax,4(%edi,%ebp,8)
+        movb 5(%esi,%ebp,4),%bl
+
+        incl %ebp
+        jnz _ConvertX86p16_32RGB888.L4
+
+    # tail
+    popl %ecx
+    andl $1,%ecx
+    jz _ConvertX86p16_32RGB888.L6
+    xorl %ebx,%ebx
+    movb (%esi),%bl                                     # ebx = lower byte pixel 1
+    movl _ConvertX86p16_32RGB888_LUT_X86(,%ebx,8),%eax  # eax = ARGB8888 of lower byte pixel 1
+    movb 1(%esi),%bl                                    # ebx = upper byte pixel 1
+    movl _ConvertX86p16_32RGB888_LUT_X86+4(,%ebx,8),%edx# edx = ARGB8888 of upper byte pixel 1
+    addl %edx,%eax
+    movl %eax,(%edi)
+    addl $2,%esi
+    addl $4,%edi
+
+_ConvertX86p16_32RGB888.L6: popl %ebp
+    jmp _x86return
+
+
+
+
+
+
+_ConvertX86p16_32BGR888: 
+
+    # check short
+    cmpl $32,%ecx
+    ja _ConvertX86p16_32BGR888.L3
+
+
+    # short loop
+    xorl %ebx,%ebx
+_ConvertX86p16_32BGR888.L1: movb (%esi),%bl             # ebx = lower byte pixel 1
+    movl _ConvertX86p16_32BGR888_LUT_X86(,%ebx,8),%eax  # eax = ABGR8888 of lower byte pixel 1
+    movb 1(%esi),%bl                                    # ebx = upper byte pixel 1
+    movl _ConvertX86p16_32BGR888_LUT_X86+4(,%ebx,8),%edx# edx = ABGR8888 of upper byte pixel 1
+    addl %edx,%eax
+    movl %eax,(%edi)
+    addl $2,%esi
+    addl $4,%edi
+    decl %ecx
+    jnz _ConvertX86p16_32BGR888.L1
+_ConvertX86p16_32BGR888.L2: 
+    jmp _x86return
+
+_ConvertX86p16_32BGR888.L3:  # save ebp
+    pushl %ebp
+
+    # save count
+    pushl %ecx
+
+    # unroll twice
+    movl %ecx,%ebp
+    shrl %ebp
+
+    # point arrays to end
+    leal (%esi,%ebp,4),%esi
+    leal (%edi,%ebp,8),%edi
+
+    # negative counter 
+    negl %ebp
+
+    # clear
+    xorl %ebx,%ebx
+    xorl %ecx,%ecx
+
+    # prestep
+    movb (%esi,%ebp,4),%cl
+    movb 1(%esi,%ebp,4),%bl
+
+_ConvertX86p16_32BGR888.L4: movl _ConvertX86p16_32BGR888_LUT_X86(,%ecx,8),%edx
+        movb 2(%esi,%ebp,4),%cl
+
+        movl _ConvertX86p16_32BGR888_LUT_X86+4(,%ebx,8),%eax
+        movb 3(%esi,%ebp,4),%bl
+
+        addl %edx,%eax
+        movl _ConvertX86p16_32BGR888_LUT_X86(,%ecx,8),%edx
+
+        movl %eax,(%edi,%ebp,8)
+        movl _ConvertX86p16_32BGR888_LUT_X86+4(,%ebx,8),%eax
+
+        addl %edx,%eax
+        movb 4(%esi,%ebp,4),%cl
+
+        movl %eax,4(%edi,%ebp,8)
+        movb 5(%esi,%ebp,4),%bl
+
+        incl %ebp
+        jnz _ConvertX86p16_32BGR888.L4
+
+    # tail
+    popl %ecx
+    andl $1,%ecx
+    jz _ConvertX86p16_32BGR888.L6
+    xorl %ebx,%ebx
+    movb (%esi),%bl                                     # ebx = lower byte pixel 1
+    movl _ConvertX86p16_32BGR888_LUT_X86(,%ebx,8),%eax  # eax = ABGR8888 of lower byte pixel 1
+    movb 1(%esi),%bl                                    # ebx = upper byte pixel 1
+    movl _ConvertX86p16_32BGR888_LUT_X86+4(,%ebx,8),%edx# edx = ABGR8888 of upper byte pixel 1
+    addl %edx,%eax
+    movl %eax,(%edi)
+    addl $2,%esi
+    addl $4,%edi
+
+_ConvertX86p16_32BGR888.L6: popl %ebp
+    jmp _x86return
+
+
+
+
+
+
+_ConvertX86p16_32RGBA888: 
+
+    # check short
+    cmpl $32,%ecx
+    ja _ConvertX86p16_32RGBA888.L3
+
+
+    # short loop
+    xorl %ebx,%ebx
+_ConvertX86p16_32RGBA888.L1: movb (%esi),%bl             # ebx = lower byte pixel 1
+    movl _ConvertX86p16_32RGBA888_LUT_X86(,%ebx,8),%eax  # eax = RGBA8888 of lower byte pixel 1
+    movb 1(%esi),%bl                                     # ebx = upper byte pixel 1
+    movl _ConvertX86p16_32RGBA888_LUT_X86+4(,%ebx,8),%edx# edx = RGBA8888 of upper byte pixel 1
+    addl %edx,%eax
+    movl %eax,(%edi)
+    addl $2,%esi
+    addl $4,%edi
+    decl %ecx
+    jnz _ConvertX86p16_32RGBA888.L1
+_ConvertX86p16_32RGBA888.L2: 
+    jmp _x86return
+
+_ConvertX86p16_32RGBA888.L3:  # save ebp
+    pushl %ebp
+
+    # save count
+    pushl %ecx
+
+    # unroll twice
+    movl %ecx,%ebp
+    shrl %ebp
+
+    # point arrays to end
+    leal (%esi,%ebp,4),%esi
+    leal (%edi,%ebp,8),%edi
+
+    # negative counter 
+    negl %ebp
+
+    # clear
+    xorl %ebx,%ebx
+    xorl %ecx,%ecx
+
+    # prestep
+    movb (%esi,%ebp,4),%cl
+    movb 1(%esi,%ebp,4),%bl
+
+_ConvertX86p16_32RGBA888.L4: movl _ConvertX86p16_32RGBA888_LUT_X86(,%ecx,8),%edx
+        movb 2(%esi,%ebp,4),%cl
+
+        movl _ConvertX86p16_32RGBA888_LUT_X86+4(,%ebx,8),%eax
+        movb 3(%esi,%ebp,4),%bl
+
+        addl %edx,%eax
+        movl _ConvertX86p16_32RGBA888_LUT_X86(,%ecx,8),%edx
+
+        movl %eax,(%edi,%ebp,8)
+        movl _ConvertX86p16_32RGBA888_LUT_X86+4(,%ebx,8),%eax
+
+        addl %edx,%eax
+        movb 4(%esi,%ebp,4),%cl
+
+        movl %eax,4(%edi,%ebp,8)
+        movb 5(%esi,%ebp,4),%bl
+
+        incl %ebp
+        jnz _ConvertX86p16_32RGBA888.L4
+
+    # tail
+    popl %ecx
+    andl $1,%ecx
+    jz _ConvertX86p16_32RGBA888.L6
+    xorl %ebx,%ebx
+    movb (%esi),%bl                                      # ebx = lower byte pixel 1
+    movl _ConvertX86p16_32RGBA888_LUT_X86(,%ebx,8),%eax  # eax = RGBA8888 of lower byte pixel 1
+    movb 1(%esi),%bl                                     # ebx = upper byte pixel 1
+    movl _ConvertX86p16_32RGBA888_LUT_X86+4(,%ebx,8),%edx# edx = RGBA8888 of upper byte pixel 1
+    addl %edx,%eax
+    movl %eax,(%edi)
+    addl $2,%esi
+    addl $4,%edi
+
+_ConvertX86p16_32RGBA888.L6: popl %ebp
+    jmp _x86return
+
+
+
+
+
+
+_ConvertX86p16_32BGRA888: 
+
+    # check short
+    cmpl $32,%ecx
+    ja _ConvertX86p16_32BGRA888.L3
+
+    # short loop
+    xorl %ebx,%ebx
+_ConvertX86p16_32BGRA888.L1: movb (%esi),%bl             # ebx = lower byte pixel 1
+    movl _ConvertX86p16_32BGRA888_LUT_X86(,%ebx,8),%eax  # eax = BGRA8888 of lower byte pixel 1
+    movb 1(%esi),%bl                                     # ebx = upper byte pixel 1
+    movl _ConvertX86p16_32BGRA888_LUT_X86+4(,%ebx,8),%edx# edx = BGRA8888 of upper byte pixel 1
+    addl %edx,%eax
+    movl %eax,(%edi)
+    addl $2,%esi
+    addl $4,%edi
+    decl %ecx
+    jnz _ConvertX86p16_32BGRA888.L1
+_ConvertX86p16_32BGRA888.L2: 
+    jmp _x86return
+
+_ConvertX86p16_32BGRA888.L3:  # save ebp
+    pushl %ebp
+
+    # save count
+    pushl %ecx
+
+    # unroll twice
+    movl %ecx,%ebp
+    shrl %ebp
+
+    # point arrays to end
+    leal (%esi,%ebp,4),%esi
+    leal (%edi,%ebp,8),%edi
+
+    # negative counter 
+    negl %ebp
+
+    # clear
+    xorl %ebx,%ebx
+    xorl %ecx,%ecx
+
+    # prestep
+    movb (%esi,%ebp,4),%cl
+    movb 1(%esi,%ebp,4),%bl
+
+_ConvertX86p16_32BGRA888.L4: movl _ConvertX86p16_32BGRA888_LUT_X86(,%ecx,8),%edx
+        movb 2(%esi,%ebp,4),%cl
+
+        movl _ConvertX86p16_32BGRA888_LUT_X86+4(,%ebx,8),%eax
+        movb 3(%esi,%ebp,4),%bl
+
+        addl %edx,%eax
+        movl _ConvertX86p16_32BGRA888_LUT_X86(,%ecx,8),%edx
+
+        movl %eax,(%edi,%ebp,8)
+        movl _ConvertX86p16_32BGRA888_LUT_X86+4(,%ebx,8),%eax
+
+        addl %edx,%eax
+        movb 4(%esi,%ebp,4),%cl
+
+        movl %eax,4(%edi,%ebp,8)
+        movb 5(%esi,%ebp,4),%bl
+
+        incl %ebp
+        jnz _ConvertX86p16_32BGRA888.L4
+
+    # tail
+    popl %ecx
+    andl $1,%ecx
+    jz _ConvertX86p16_32BGRA888.L6
+    xorl %ebx,%ebx
+    movb (%esi),%bl                                      # ebx = lower byte pixel 1
+    movl _ConvertX86p16_32BGRA888_LUT_X86(,%ebx,8),%eax  # eax = BGRA8888 of lower byte pixel 1
+    movb 1(%esi),%bl                                     # ebx = upper byte pixel 1
+    movl _ConvertX86p16_32BGRA888_LUT_X86+4(,%ebx,8),%edx# edx = BGRA8888 of upper byte pixel 1
+    addl %edx,%eax
+    movl %eax,(%edi)
+    addl $2,%esi
+    addl $4,%edi
+
+_ConvertX86p16_32BGRA888.L6: popl %ebp
+    jmp _x86return
+
+
+
+
+
+
+_ConvertX86p16_24RGB888: 
+
+    # check short
+    cmpl $32,%ecx
+    ja _ConvertX86p16_24RGB888.L3
+
+
+    # short loop
+    xorl %edx,%edx
+_ConvertX86p16_24RGB888.L1: movb (%esi),%dl
+    movl _ConvertX86p16_32RGB888_LUT_X86(,%edx,8),%eax    # eax = ARGB8888 of lower byte
+    movb 1(%esi),%dl
+    movl _ConvertX86p16_32RGB888_LUT_X86+4(,%edx,8),%ebx  # ebx = ARGB8888 of upper byte
+    addl %ebx,%eax                                        # eax = ARGB8888 pixel
+    movb %al,(%edi)
+    movb %ah,1(%edi)
+    shrl $16,%eax
+    movb %al,2(%edi)
+    addl $2,%esi
+    addl $3,%edi
+    decl %ecx
+    jnz _ConvertX86p16_24RGB888.L1
+_ConvertX86p16_24RGB888.L2: jmp _x86return
+
+
+_ConvertX86p16_24RGB888.L3:  # clear edx
+    xorl %edx,%edx
+
+_ConvertX86p16_24RGB888.L4:  # head
+    movl %edi,%eax
+    andl $0b11,%eax
+    jz _ConvertX86p16_24RGB888.L5
+    movb (%esi),%dl
+    movl _ConvertX86p16_32RGB888_LUT_X86(,%edx,8),%eax    # eax = ARGB8888 of lower byte
+    movb 1(%esi),%dl
+    movl _ConvertX86p16_32RGB888_LUT_X86+4(,%edx,8),%ebx  # ebx = ARGB8888 of upper byte
+    addl %ebx,%eax                                        # eax = ARGB8888 pixel
+    movb %al,(%edi)
+    movb %ah,1(%edi)
+    shrl $16,%eax
+    movb %al,2(%edi)
+    addl $2,%esi
+    addl $3,%edi
+    decl %ecx
+    jmp _ConvertX86p16_24RGB888.L4
+
+_ConvertX86p16_24RGB888.L5:  # unroll 4 times
+    pushl %ebp
+    movl %ecx,%ebp
+    shrl $2,%ebp
+
+    # clear ebx
+    xorl %ebx,%ebx
+
+    # save count
+    pushl %ecx
+
+    # prestep
+    movb (%esi),%bl                                     # ebx = lower byte pixel 1
+    movb 1(%esi),%dl                                    # edx = upper byte pixel 1
+
+_ConvertX86p16_24RGB888.L6: movl _ConvertX86p16_32RGB888_LUT_X86(,%ebx,8),%eax # eax = ARGB8888 of lower byte pixel 1
+        movb 2(%esi),%bl                                    # ebx = lower byte pixel 2
+
+        movl _ConvertX86p16_32RGB888_LUT_X86+4(,%edx,8),%ecx    # ecx = ARGB8888 of upper byte pixel 1
+        movb 3(%esi),%dl                                    # edx = upper byte pixel 2
+
+        pushl %ebp                                          # save ebp
+        addl %ecx,%eax                                      # eax = ARGB8888 of pixel 1
+
+        movl _ConvertX86p16_32RGB888_LUT_X86(,%ebx,8),%ebp      # ebp = ARGB8888 of lower byte pixel 2
+        movl _ConvertX86p16_32RGB888_LUT_X86+4(,%edx,8),%ecx    # ecx = ARGB8888 of upper byte pixel 2
+
+        movb 4(%esi),%bl                                    # ebx = lower byte pixel 3
+        addl %ebp,%ecx                                      # ecx = ARGB8888 of pixel 2
+
+        shll $24,%ebp                                       # ebp = [b][0][0][0] of pixel 2
+        movb 5(%esi),%dl                                    # edx = upper byte pixel 3
+
+        shrl $8,%ecx                                        # ecx = [0][0][r][g] pixel 2
+        addl %ebp,%eax                                      # eax = [b2][r1][g1][b1] (done)
+
+        movl %eax,(%edi)                                    # store dword 1
+        movl _ConvertX86p16_32RGB888_LUT_X86+4(,%edx,8),%eax    # eax = ARGB8888 of upper byte pixel 3
+
+        movl _ConvertX86p16_32RGB888_LUT_X86(,%ebx,8),%ebp      # ebp = ARGB8888 of lower byte pixel 3
+        movb 6(%esi),%bl                                    # ebx = lower byte pixel 4
+
+        addl %eax,%ebp                                      # ebp = ARGB8888 of pixel 3
+        movb 7(%esi),%dl                                    # edx = upper byte pixel 4
+
+        shll $16,%ebp                                       # ebp = [g][b][0][0] pixel 3
+
+        shrl $16,%eax                                       #  al = red component of pixel 3
+        addl %ecx,%ebp                                      # ebp = [g3][b3][r2][g2] (done)
+
+        movl %ebp,4(%edi)                                   # store dword 2
+        movl _ConvertX86p16_32RGB888_LUT_X86(,%ebx,8),%ecx      # ebx = ARGB8888 of lower byte pixel 4
+
+        movl _ConvertX86p16_32RGB888_LUT_X86+4(,%edx,8),%ebp    # ebp = ARGB8888 of upper byte pixel 4
+        movb 4*2+0(%esi),%bl                                # ebx = lower byte pixel 1
+
+        addl %ebp,%ecx                                      # ecx = ARGB8888 of pixel 4
+        movb 4*2+1(%esi),%dl                                # edx = upper byte pixel 1
+
+        shll $8,%ecx                                        # ecx = [r][g][b][0]
+        popl %ebp                                           # restore ebp
+
+        movb %al,%cl                                        # ecx = [r4][g4][b4][r3] (done)
+        addl $4*2,%esi
+
+        movl %ecx,8(%edi)                                   # store dword 3
+        addl $3*4,%edi
+
+        decl %ebp
+        jz _ConvertX86p16_24RGB888.L7
+
+        jmp _ConvertX86p16_24RGB888.L6
+
+_ConvertX86p16_24RGB888.L7:  # check tail
+    popl %ecx
+    andl $0b11,%ecx
+    jz _ConvertX86p16_24RGB888.L9
+
+_ConvertX86p16_24RGB888.L8:  # tail
+    movb (%esi),%dl
+    movl _ConvertX86p16_32RGB888_LUT_X86(,%edx,8),%eax    # eax = ARGB8888 of lower byte
+    movb 1(%esi),%dl
+    movl _ConvertX86p16_32RGB888_LUT_X86+4(,%edx,8),%ebx  # ebx = ARGB8888 of upper byte
+    addl %ebx,%eax                                    # eax = ARGB8888 pixel
+    movb %al,(%edi)
+    movb %ah,1(%edi)
+    shrl $16,%eax
+    movb %al,2(%edi)
+    addl $2,%esi
+    addl $3,%edi
+    decl %ecx
+    jnz _ConvertX86p16_24RGB888.L8
+
+_ConvertX86p16_24RGB888.L9: popl %ebp
+    jmp _x86return
+
+
+
+
+
+_ConvertX86p16_24BGR888: 
+
+    # check short
+    cmpl $32,%ecx
+    ja _ConvertX86p16_24BGR888.L3
+
+
+    # short loop
+    xorl %edx,%edx
+_ConvertX86p16_24BGR888.L1: movb (%esi),%dl
+    movl _ConvertX86p16_32BGR888_LUT_X86(,%edx,8),%eax    # eax = ABGR8888 of lower byte
+    movb 1(%esi),%dl
+    movl _ConvertX86p16_32BGR888_LUT_X86+4(,%edx,8),%ebx  # ebx = ABGR8888 of upper byte
+    addl %ebx,%eax                                    # eax = ABGR8888 pixel
+    movb %al,(%edi)
+    movb %ah,1(%edi)
+    shrl $16,%eax
+    movb %al,2(%edi)
+    addl $2,%esi
+    addl $3,%edi
+    decl %ecx
+    jnz _ConvertX86p16_24BGR888.L1
+_ConvertX86p16_24BGR888.L2: 
+    jmp _x86return
+
+
+_ConvertX86p16_24BGR888.L3:  # clear edx
+    xorl %edx,%edx
+
+_ConvertX86p16_24BGR888.L4:  # head
+    movl %edi,%eax
+    andl $0b11,%eax
+    jz _ConvertX86p16_24BGR888.L5
+    movb (%esi),%dl
+    movl _ConvertX86p16_32BGR888_LUT_X86(,%edx,8),%eax    # eax = ABGR8888 of lower byte
+    movb 1(%esi),%dl
+    movl _ConvertX86p16_32BGR888_LUT_X86+4(,%edx,8),%ebx  # ebx = ABGR8888 of upper byte
+    addl %ebx,%eax                                    # eax = ABGR8888 pixel
+    movb %al,(%edi)
+    movb %ah,1(%edi)
+    shrl $16,%eax
+    movb %al,2(%edi)
+    addl $2,%esi
+    addl $3,%edi
+    decl %ecx
+    jmp _ConvertX86p16_24BGR888.L4
+
+_ConvertX86p16_24BGR888.L5:  # unroll 4 times
+    pushl %ebp
+    movl %ecx,%ebp
+    shrl $2,%ebp
+
+    # clear ebx
+    xorl %ebx,%ebx
+
+    # save count
+    pushl %ecx
+
+    # prestep
+    movb (%esi),%bl                                     # ebx = lower byte pixel 1
+    movb 1(%esi),%dl                                    # edx = upper byte pixel 1
+
+_ConvertX86p16_24BGR888.L6: movl _ConvertX86p16_32BGR888_LUT_X86(,%ebx,8),%eax # eax = ABGR8888 of lower byte pixel 1
+        movb 2(%esi),%bl                                    # ebx = lower byte pixel 2
+
+        movl _ConvertX86p16_32BGR888_LUT_X86+4(,%edx,8),%ecx    # ecx = ABGR8888 of upper byte pixel 1
+        movb 3(%esi),%dl                                    # edx = upper byte pixel 2
+
+        pushl %ebp                                          # save ebp
+        addl %ecx,%eax                                      # eax = ABGR8888 of pixel 1
+
+        movl _ConvertX86p16_32BGR888_LUT_X86(,%ebx,8),%ecx      # ecx = ABGR8888 of lower byte pixel 2
+        movl _ConvertX86p16_32BGR888_LUT_X86+4(,%edx,8),%ebp    # ebp = ABGR8888 of upper byte pixel 2
+
+        movb 4(%esi),%bl                                    # ebx = lower byte pixel 3
+        addl %ebp,%ecx                                      # ecx = ABGR8888 of pixel 2
+
+        shll $24,%ebp                                       # ebp = [r][0][0][0] of pixel 2
+        movb 5(%esi),%dl                                    # edx = upper byte pixel 3
+
+        shrl $8,%ecx                                        # ecx = [0][0][b][g] pixel 2
+        addl %ebp,%eax                                      # eax = [r2][b1][g1][r1] (done)
+
+        movl %eax,(%edi)                                    # store dword 1
+        movl _ConvertX86p16_32BGR888_LUT_X86+4(,%edx,8),%ebp    # ebp = ABGR8888 of upper byte pixel 3
+
+        movl _ConvertX86p16_32BGR888_LUT_X86(,%ebx,8),%eax      # eax = ABGR8888 of lower byte pixel 3
+        movb 6(%esi),%bl                                    # ebx = lower byte pixel 4
+
+        addl %eax,%ebp                                      # ebp = ABGR8888 of pixel 3
+        movb 7(%esi),%dl                                    # edx = upper byte pixel 4
+
+        shll $16,%ebp                                       # ebp = [g][r][0][0] pixel 3
+
+        shrl $16,%eax                                       #  al = blue component of pixel 3
+        addl %ecx,%ebp                                      # ebp = [g3][r3][b2][g2] (done)
+
+        movl %ebp,4(%edi)                                   # store dword 2
+        movl _ConvertX86p16_32BGR888_LUT_X86(,%ebx,8),%ecx      # ebx = ABGR8888 of lower byte pixel 4
+
+        movl _ConvertX86p16_32BGR888_LUT_X86+4(,%edx,8),%ebp    # ebp = ABGR8888 of upper byte pixel 4
+        movb 4*2+0(%esi),%bl                                # ebx = lower byte pixel 1
+
+        addl %ebp,%ecx                                      # ecx = ABGR8888 of pixel 4
+        movb 4*2+1(%esi),%dl                                # edx = upper byte pixel 1
+
+        shll $8,%ecx                                        # ecx = [b][g][r][0]
+        popl %ebp                                           # restore ebp
+
+        movb %al,%cl                                        # ecx = [b4][g4][r4][b3] (done)
+        addl $4*2,%esi
+
+        movl %ecx,8(%edi)                                   # store dword 3
+        addl $3*4,%edi
+
+        decl %ebp
+        jz _ConvertX86p16_24BGR888.L7
+
+        jmp _ConvertX86p16_24BGR888.L6
+
+_ConvertX86p16_24BGR888.L7:  # check tail
+    popl %ecx
+    andl $0b11,%ecx
+    jz _ConvertX86p16_24BGR888.L9
+
+_ConvertX86p16_24BGR888.L8:  # tail
+    movb (%esi),%dl
+    movl _ConvertX86p16_32BGR888_LUT_X86(,%edx,8),%eax    # eax = ABGR8888 of lower byte
+    movb 1(%esi),%dl
+    movl _ConvertX86p16_32BGR888_LUT_X86+4(,%edx,8),%ebx  # ebx = ABGR8888 of upper byte
+    addl %ebx,%eax                                    # eax = ABGR8888 pixel
+    movb %al,(%edi)
+    movb %ah,1(%edi)
+    shrl $16,%eax
+    movb %al,2(%edi)
+    addl $2,%esi
+    addl $3,%edi
+    decl %ecx
+    jnz _ConvertX86p16_24BGR888.L8
+
+_ConvertX86p16_24BGR888.L9: popl %ebp
+    jmp _x86return
+
+
+
+
+_ConvertX86p16_16BGR565: 
+
+    # check short
+    cmpl $16,%ecx
+    ja _ConvertX86p16_16BGR565.L3
+
+
+_ConvertX86p16_16BGR565.L1:  # short loop
+    movb (%esi),%al
+    movb 1(%esi),%ah
+    movl %eax,%ebx
+    movl %eax,%edx
+    shrl $11,%eax
+    andl $0b11111,%eax
+    andl $0b11111100000,%ebx
+    shll $11,%edx
+    addl %ebx,%eax
+    addl %edx,%eax
+    movb %al,(%edi)
+    movb %ah,1(%edi)
+    addl $2,%esi
+    addl $2,%edi
+    decl %ecx
+    jnz _ConvertX86p16_16BGR565.L1
+_ConvertX86p16_16BGR565.L2: 
+    jmp _x86return
+
+_ConvertX86p16_16BGR565.L3:  # head
+    movl %edi,%eax
+    andl $0b11,%eax
+    jz _ConvertX86p16_16BGR565.L4
+    movb (%esi),%al
+    movb 1(%esi),%ah
+    movl %eax,%ebx
+    movl %eax,%edx
+    shrl $11,%eax
+    andl $0b11111,%eax
+    andl $0b11111100000,%ebx
+    shll $11,%edx
+    addl %ebx,%eax
+    addl %edx,%eax
+    movb %al,(%edi)
+    movb %ah,1(%edi)
+    addl $2,%esi
+    addl $2,%edi
+    decl %ecx
+
+_ConvertX86p16_16BGR565.L4:  # save count
+    pushl %ecx
+
+    # unroll twice
+    shrl %ecx
+
+    # point arrays to end
+    leal (%esi,%ecx,4),%esi
+    leal (%edi,%ecx,4),%edi
+
+    # negative counter 
+    negl %ecx
+    jmp _ConvertX86p16_16BGR565.L6
+
+_ConvertX86p16_16BGR565.L5: movl %eax,-4(%edi,%ecx,4)
+_ConvertX86p16_16BGR565.L6: movl (%esi,%ecx,4),%eax
+
+        movl (%esi,%ecx,4),%ebx
+        andl $0x07E007E0,%eax
+
+        movl (%esi,%ecx,4),%edx
+        andl $0x0F800F800,%ebx
+
+        shrl $11,%ebx
+        andl $0x001F001F,%edx
+
+        shll $11,%edx
+        addl %ebx,%eax
+
+        addl %edx,%eax
+        incl %ecx
+
+        jnz _ConvertX86p16_16BGR565.L5
+
+    movl %eax,-4(%edi,%ecx,4)
+
+    # tail
+    popl %ecx
+    andl $1,%ecx
+    jz _ConvertX86p16_16BGR565.L7
+    movb (%esi),%al
+    movb 1(%esi),%ah
+    movl %eax,%ebx
+    movl %eax,%edx
+    shrl $11,%eax
+    andl $0b11111,%eax
+    andl $0b11111100000,%ebx
+    shll $11,%edx
+    addl %ebx,%eax
+    addl %edx,%eax
+    movb %al,(%edi)
+    movb %ah,1(%edi)
+    addl $2,%esi
+    addl $2,%edi
+
+_ConvertX86p16_16BGR565.L7: 
+    jmp _x86return
+
+
+
+
+
+
+_ConvertX86p16_16RGB555: 
+
+    # check short
+    cmpl $32,%ecx
+    ja _ConvertX86p16_16RGB555.L3
+
+
+_ConvertX86p16_16RGB555.L1:  # short loop
+    movb (%esi),%al
+    movb 1(%esi),%ah
+    movl %eax,%ebx
+    shrl %ebx
+    andl $0b0111111111100000,%ebx
+    andl $0b0000000000011111,%eax
+    addl %ebx,%eax
+    movb %al,(%edi)
+    movb %ah,1(%edi)
+    addl $2,%esi
+    addl $2,%edi
+    decl %ecx
+    jnz _ConvertX86p16_16RGB555.L1
+_ConvertX86p16_16RGB555.L2: 
+    jmp _x86return
+
+_ConvertX86p16_16RGB555.L3:  # head
+    movl %edi,%eax
+    andl $0b11,%eax
+    jz _ConvertX86p16_16RGB555.L4
+    movb (%esi),%al
+    movb 1(%esi),%ah
+    movl %eax,%ebx
+    shrl %ebx
+    andl $0b0111111111100000,%ebx
+    andl $0b0000000000011111,%eax
+    addl %ebx,%eax
+    movb %al,(%edi)
+    movb %ah,1(%edi)
+    addl $2,%esi
+    addl $2,%edi
+    decl %ecx
+
+_ConvertX86p16_16RGB555.L4:  # save ebp
+    pushl %ebp
+
+    # save count
+    pushl %ecx
+
+    # unroll four times
+    shrl $2,%ecx
+
+    # point arrays to end
+    leal (%esi,%ecx,8),%esi
+    leal (%edi,%ecx,8),%edi
+
+    # negative counter 
+    xorl %ebp,%ebp
+    subl %ecx,%ebp
+
+_ConvertX86p16_16RGB555.L5: movl (%esi,%ebp,8),%eax # agi?
+        movl 4(%esi,%ebp,8),%ecx
+
+        movl %eax,%ebx
+        movl %ecx,%edx
+
+        andl $0x0FFC0FFC0,%eax
+        andl $0x0FFC0FFC0,%ecx
+
+        shrl %eax
+        andl $0x001F001F,%ebx
+
+        shrl %ecx
+        andl $0x001F001F,%edx
+
+        addl %ebx,%eax
+        addl %edx,%ecx
+
+        movl %eax,(%edi,%ebp,8)
+        movl %ecx,4(%edi,%ebp,8)
+
+        incl %ebp
+        jnz _ConvertX86p16_16RGB555.L5
+
+    # tail
+    popl %ecx
+_ConvertX86p16_16RGB555.L6: andl $0b11,%ecx
+    jz _ConvertX86p16_16RGB555.L7
+    movb (%esi),%al
+    movb 1(%esi),%ah
+    movl %eax,%ebx
+    shrl %ebx
+    andl $0b0111111111100000,%ebx
+    andl $0b0000000000011111,%eax
+    addl %ebx,%eax
+    movb %al,(%edi)
+    movb %ah,1(%edi)
+    addl $2,%esi
+    addl $2,%edi
+    decl %ecx
+    jmp _ConvertX86p16_16RGB555.L6
+
+_ConvertX86p16_16RGB555.L7: popl %ebp
+    jmp _x86return
+
+
+
+
+
+
+_ConvertX86p16_16BGR555: 
+
+    # check short
+    cmpl $16,%ecx
+    ja _ConvertX86p16_16BGR555.L3
+
+
+_ConvertX86p16_16BGR555.L1:  # short loop
+    movb (%esi),%al
+    movb 1(%esi),%ah
+    movl %eax,%ebx
+    movl %eax,%edx
+    shrl $11,%eax
+    andl $0b11111,%eax
+    shrl %ebx
+    andl $0b1111100000,%ebx
+    shll $10,%edx
+    andl $0b0111110000000000,%edx
+    addl %ebx,%eax
+    addl %edx,%eax
+    movb %al,(%edi)
+    movb %ah,1(%edi)
+    addl $2,%esi
+    addl $2,%edi
+    decl %ecx
+    jnz _ConvertX86p16_16BGR555.L1
+_ConvertX86p16_16BGR555.L2: 
+    jmp _x86return
+
+_ConvertX86p16_16BGR555.L3:  # head
+    movl %edi,%eax
+    andl $0b11,%eax
+    jz _ConvertX86p16_16BGR555.L4
+    movb (%esi),%al
+    movb 1(%esi),%ah
+    movl %eax,%ebx
+    movl %eax,%edx
+    shrl $11,%eax
+    andl $0b11111,%eax
+    shrl %ebx
+    andl $0b1111100000,%ebx
+    shll $10,%edx
+    andl $0b0111110000000000,%edx
+    addl %ebx,%eax
+    addl %edx,%eax
+    movb %al,(%edi)
+    movb %ah,1(%edi)
+    addl $2,%esi
+    addl $2,%edi
+    decl %ecx
+
+_ConvertX86p16_16BGR555.L4:  # save count
+    pushl %ecx
+
+    # unroll twice
+    shrl %ecx
+
+    # point arrays to end
+    leal (%esi,%ecx,4),%esi
+    leal (%edi,%ecx,4),%edi
+
+    # negative counter 
+    negl %ecx
+    jmp _ConvertX86p16_16BGR555.L6
+
+_ConvertX86p16_16BGR555.L5: movl %eax,-4(%edi,%ecx,4)
+_ConvertX86p16_16BGR555.L6: movl (%esi,%ecx,4),%eax
+
+        shrl %eax
+        movl (%esi,%ecx,4),%ebx
+
+        andl $0x03E003E0,%eax
+        movl (%esi,%ecx,4),%edx
+
+        andl $0x0F800F800,%ebx
+
+        shrl $11,%ebx
+        andl $0x001F001F,%edx
+
+        shll $10,%edx
+        addl %ebx,%eax
+
+        addl %edx,%eax
+        incl %ecx
+
+        jnz _ConvertX86p16_16BGR555.L5
+
+    movl %eax,-4(%edi,%ecx,4)
+
+    # tail
+    popl %ecx
+    andl $1,%ecx
+    jz _ConvertX86p16_16BGR555.L7
+    movb (%esi),%al
+    movb 1(%esi),%ah
+    movl %eax,%ebx
+    movl %eax,%edx
+    shrl $11,%eax
+    andl $0b11111,%eax
+    shrl %ebx
+    andl $0b1111100000,%ebx
+    shll $10,%edx
+    andl $0b0111110000000000,%edx
+    addl %ebx,%eax
+    addl %edx,%eax
+    movb %al,(%edi)
+    movb %ah,1(%edi)
+    addl $2,%esi
+    addl $2,%edi
+
+_ConvertX86p16_16BGR555.L7: 
+    jmp _x86return
+
+
+
+
+
+
+_ConvertX86p16_8RGB332: 
+
+    # check short
+    cmpl $16,%ecx
+    ja _ConvertX86p16_8RGB332.L3
+
+
+_ConvertX86p16_8RGB332.L1:  # short loop
+    movb (%esi),%al
+    movb 1(%esi),%ah
+    movl %eax,%ebx
+    movl %eax,%edx
+    andl $0b11000,%eax          # blue
+    shrl $3,%eax
+    andl $0b11100000000,%ebx    # green
+    shrl $6,%ebx
+    andl $0b1110000000000000,%edx # red
+    shrl $8,%edx
+    addl %ebx,%eax
+    addl %edx,%eax
+    movb %al,(%edi)
+    addl $2,%esi
+    incl %edi
+    decl %ecx
+    jnz _ConvertX86p16_8RGB332.L1
+_ConvertX86p16_8RGB332.L2: 
+    jmp _x86return
+
+_ConvertX86p16_8RGB332.L3: movl %edi,%eax
+    andl $0b11,%eax
+    jz _ConvertX86p16_8RGB332.L4
+    movb (%esi),%al
+    movb 1(%esi),%ah
+    movl %eax,%ebx
+    movl %eax,%edx
+    andl $0b11000,%eax          # blue
+    shrl $3,%eax
+    andl $0b11100000000,%ebx    # green
+    shrl $6,%ebx
+    andl $0b1110000000000000,%edx # red
+    shrl $8,%edx
+    addl %ebx,%eax
+    addl %edx,%eax
+    movb %al,(%edi)
+    addl $2,%esi
+    incl %edi
+    decl %ecx
+    jmp _ConvertX86p16_8RGB332.L3
+
+_ConvertX86p16_8RGB332.L4:  # save ebp
+    pushl %ebp
+
+    # save count
+    pushl %ecx
+
+    # unroll 4 times
+    shrl $2,%ecx
+
+    # prestep
+    movb (%esi),%dl
+    movb 1(%esi),%bl
+    movb 2(%esi),%dh
+
+_ConvertX86p16_8RGB332.L5: shll $16,%edx
+        movb 3(%esi),%bh
+
+        shll $16,%ebx
+        movb 4(%esi),%dl
+
+        movb 6(%esi),%dh
+        movb 5(%esi),%bl
+
+        andl $0b00011000000110000001100000011000,%edx
+        movb 7(%esi),%bh
+
+        rorl $16+3,%edx
+        movl %ebx,%eax                                  # setup eax for reds
+
+        andl $0b00000111000001110000011100000111,%ebx
+        andl $0b11100000111000001110000011100000,%eax   # reds
+
+        rorl $16-2,%ebx
+        addl $8,%esi
+
+        rorl $16,%eax
+        addl $4,%edi
+
+        addl %ebx,%eax
+        movb 1(%esi),%bl                                # greens
+
+        addl %edx,%eax
+        movb (%esi),%dl                                 # blues
+
+        movl %eax,-4(%edi)
+        movb 2(%esi),%dh
+
+        decl %ecx
+        jnz _ConvertX86p16_8RGB332.L5
+
+    # check tail
+    popl %ecx
+    andl $0b11,%ecx
+    jz _ConvertX86p16_8RGB332.L7
+
+_ConvertX86p16_8RGB332.L6:  # tail
+    movb (%esi),%al
+    movb 1(%esi),%ah
+    movl %eax,%ebx
+    movl %eax,%edx
+    andl $0b11000,%eax          # blue
+    shrl $3,%eax
+    andl $0b11100000000,%ebx    # green
+    shrl $6,%ebx
+    andl $0b1110000000000000,%edx # red
+    shrl $8,%edx
+    addl %ebx,%eax
+    addl %edx,%eax
+    movb %al,(%edi)
+    addl $2,%esi
+    incl %edi
+    decl %ecx
+    jnz _ConvertX86p16_8RGB332.L6
+
+_ConvertX86p16_8RGB332.L7: popl %ebp
+    jmp _x86return
+

+ 1043 - 0
packages/hermes/src/i386/x86p_32.as

@@ -0,0 +1,1043 @@
+#
+# x86 format converters for HERMES
+# Some routines Copyright (c) 1998 Christian Nentwich ([email protected])
+# This source code is licensed under the GNU LGPL
+# 
+# Please refer to the file COPYING.LIB contained in the distribution for
+# licensing conditions          
+#
+# Most routines are (c) Glenn Fiedler ([email protected]), used with permission
+# 
+
+
+
+.globl _ConvertX86p32_32BGR888
+.globl _ConvertX86p32_32RGBA888
+.globl _ConvertX86p32_32BGRA888
+.globl _ConvertX86p32_24RGB888
+.globl _ConvertX86p32_24BGR888
+.globl _ConvertX86p32_16RGB565
+.globl _ConvertX86p32_16BGR565
+.globl _ConvertX86p32_16RGB555
+.globl _ConvertX86p32_16BGR555
+.globl _ConvertX86p32_8RGB332
+
+.extern _x86return
+
+.text
+
+
+## _Convert_*
+## Paramters:   
+##   ESI = source 
+##   EDI = dest
+##   ECX = amount (NOT 0!!! (the _ConvertX86 routine checks for that though))
+## Destroys:
+##   EAX, EBX, EDX
+
+
+_ConvertX86p32_32BGR888: 
+
+    # check short
+    cmpl $32,%ecx
+    ja _ConvertX86p32_32BGR888.L3
+
+_ConvertX86p32_32BGR888.L1:  # short loop
+    movl (%esi),%edx
+    bswapl %edx
+    rorl $8,%edx
+    movl %edx,(%edi)
+    addl $4,%esi
+    addl $4,%edi
+    decl %ecx
+    jnz _ConvertX86p32_32BGR888.L1
+_ConvertX86p32_32BGR888.L2: 
+    jmp _x86return
+
+_ConvertX86p32_32BGR888.L3:  # save ebp
+    pushl %ebp
+
+    # unroll four times
+    movl %ecx,%ebp
+    shrl $2,%ebp
+
+    # save count
+    pushl %ecx
+
+_ConvertX86p32_32BGR888.L4: movl (%esi),%eax
+        movl 4(%esi),%ebx
+
+        bswapl %eax
+
+        bswapl %ebx
+
+        rorl $8,%eax
+        movl 8(%esi),%ecx
+
+        rorl $8,%ebx
+        movl 12(%esi),%edx
+
+        bswapl %ecx
+
+        bswapl %edx
+
+        rorl $8,%ecx
+        movl %eax,(%edi)
+
+        rorl $8,%edx
+        movl %ebx,4(%edi)
+
+        movl %ecx,8(%edi)
+        movl %edx,12(%edi)
+
+        addl $16,%esi
+        addl $16,%edi
+
+        decl %ebp
+        jnz _ConvertX86p32_32BGR888.L4
+
+    # check tail
+    popl %ecx
+    andl $0b11,%ecx
+    jz _ConvertX86p32_32BGR888.L6
+
+_ConvertX86p32_32BGR888.L5:  # tail loop
+    movl (%esi),%edx
+    bswapl %edx
+    rorl $8,%edx
+    movl %edx,(%edi)
+    addl $4,%esi
+    addl $4,%edi
+    decl %ecx
+    jnz _ConvertX86p32_32BGR888.L5
+
+_ConvertX86p32_32BGR888.L6: popl %ebp
+    jmp _x86return
+
+
+
+
+_ConvertX86p32_32RGBA888: 
+
+    # check short
+    cmpl $32,%ecx
+    ja _ConvertX86p32_32RGBA888.L3
+
+_ConvertX86p32_32RGBA888.L1:  # short loop
+    movl (%esi),%edx
+    roll $8,%edx
+    movl %edx,(%edi)
+    addl $4,%esi
+    addl $4,%edi
+    decl %ecx
+    jnz _ConvertX86p32_32RGBA888.L1
+_ConvertX86p32_32RGBA888.L2: 
+    jmp _x86return
+
+_ConvertX86p32_32RGBA888.L3:  # save ebp
+    pushl %ebp
+
+    # unroll four times
+    movl %ecx,%ebp
+    shrl $2,%ebp
+
+    # save count
+    pushl %ecx
+
+_ConvertX86p32_32RGBA888.L4: movl (%esi),%eax
+        movl 4(%esi),%ebx
+
+        roll $8,%eax
+        movl 8(%esi),%ecx
+
+        roll $8,%ebx
+        movl 12(%esi),%edx
+
+        roll $8,%ecx
+        movl %eax,(%edi)
+
+        roll $8,%edx
+        movl %ebx,4(%edi)
+
+        movl %ecx,8(%edi)
+        movl %edx,12(%edi)
+
+        addl $16,%esi
+        addl $16,%edi
+
+        decl %ebp
+        jnz _ConvertX86p32_32RGBA888.L4
+
+    # check tail
+    popl %ecx
+    andl $0b11,%ecx
+    jz _ConvertX86p32_32RGBA888.L6
+
+_ConvertX86p32_32RGBA888.L5:  # tail loop
+    movl (%esi),%edx
+    roll $8,%edx
+    movl %edx,(%edi)
+    addl $4,%esi
+    addl $4,%edi
+    decl %ecx
+    jnz _ConvertX86p32_32RGBA888.L5
+
+_ConvertX86p32_32RGBA888.L6: popl %ebp
+    jmp _x86return
+
+
+
+
+_ConvertX86p32_32BGRA888: 
+
+    # check short
+    cmpl $32,%ecx
+    ja _ConvertX86p32_32BGRA888.L3
+
+_ConvertX86p32_32BGRA888.L1:  # short loop
+    movl (%esi),%edx
+    bswapl %edx
+    movl %edx,(%edi)
+    addl $4,%esi
+    addl $4,%edi
+    decl %ecx
+    jnz _ConvertX86p32_32BGRA888.L1
+_ConvertX86p32_32BGRA888.L2: 
+    jmp _x86return
+
+_ConvertX86p32_32BGRA888.L3:  # save ebp
+    pushl %ebp
+
+    # unroll four times
+    movl %ecx,%ebp
+    shrl $2,%ebp
+
+    # save count
+    pushl %ecx
+
+_ConvertX86p32_32BGRA888.L4: movl (%esi),%eax
+        movl 4(%esi),%ebx
+
+        movl 8(%esi),%ecx
+        movl 12(%esi),%edx
+
+        bswapl %eax
+
+        bswapl %ebx
+
+        bswapl %ecx
+
+        bswapl %edx
+
+        movl %eax,(%edi)
+        movl %ebx,4(%edi)
+
+        movl %ecx,8(%edi)
+        movl %edx,12(%edi)
+
+        addl $16,%esi
+        addl $16,%edi
+
+        decl %ebp
+        jnz _ConvertX86p32_32BGRA888.L4
+
+    # check tail
+    popl %ecx
+    andl $0b11,%ecx
+    jz _ConvertX86p32_32BGRA888.L6
+
+_ConvertX86p32_32BGRA888.L5:  # tail loop
+    movl (%esi),%edx
+    bswapl %edx
+    movl %edx,(%edi)
+    addl $4,%esi
+    addl $4,%edi
+    decl %ecx
+    jnz _ConvertX86p32_32BGRA888.L5
+
+_ConvertX86p32_32BGRA888.L6: popl %ebp
+    jmp _x86return
+
+
+
+
+## 32 bit RGB 888 to 24 BIT RGB 888
+
+_ConvertX86p32_24RGB888: 
+
+        # check short
+        cmpl $32,%ecx
+        ja _ConvertX86p32_24RGB888.L3
+
+_ConvertX86p32_24RGB888.L1:  # short loop
+        movb (%esi),%al
+        movb 1(%esi),%bl
+        movb 2(%esi),%dl
+        movb %al,(%edi)
+        movb %bl,1(%edi)
+        movb %dl,2(%edi)
+        addl $4,%esi
+        addl $3,%edi
+        decl %ecx
+        jnz _ConvertX86p32_24RGB888.L1
+_ConvertX86p32_24RGB888.L2: 
+        jmp _x86return
+
+_ConvertX86p32_24RGB888.L3:  #        head
+        movl %edi,%edx
+        andl $0b11,%edx
+        jz _ConvertX86p32_24RGB888.L4
+        movb (%esi),%al
+        movb 1(%esi),%bl
+        movb 2(%esi),%dl
+        movb %al,(%edi)
+        movb %bl,1(%edi)
+        movb %dl,2(%edi)
+        addl $4,%esi
+        addl $3,%edi
+        decl %ecx
+        jmp _ConvertX86p32_24RGB888.L3
+
+_ConvertX86p32_24RGB888.L4:  # unroll 4 times
+        pushl %ebp
+        movl %ecx,%ebp
+        shrl $2,%ebp
+
+    # save count
+        pushl %ecx
+
+_ConvertX86p32_24RGB888.L5: movl (%esi),%eax # first dword            eax = [A][R][G][B]
+        movl 4(%esi),%ebx               # second dword           ebx = [a][r][g][b]
+
+        shll $8,%eax                    #                        eax = [R][G][B][.]
+        movl 12(%esi),%ecx              # third dword            ecx = [a][r][g][b]
+
+        shll $8,%ebx                    #                        ebx = [r][g][b][.]
+        movb 4(%esi),%al                #                        eax = [R][G][B][b]
+
+        rorl $8,%eax                    #                        eax = [b][R][G][B] (done)
+        movb 8+1(%esi),%bh              #                        ebx = [r][g][G][.]
+
+        movl %eax,(%edi)
+        addl $3*4,%edi
+
+        shll $8,%ecx                    #                        ecx = [r][g][b][.]
+        movb 8+0(%esi),%bl              #                        ebx = [r][g][G][B]
+
+        roll $16,%ebx                   #                        ebx = [G][B][r][g] (done)
+        movb 8+2(%esi),%cl              #                        ecx = [r][g][b][R] (done)
+
+        movl %ebx,4-3*4(%edi)
+        addl $4*4,%esi
+
+        movl %ecx,8-3*4(%edi)
+        decl %ebp
+
+        jnz _ConvertX86p32_24RGB888.L5
+
+    # check tail
+        popl %ecx
+        andl $0b11,%ecx
+        jz _ConvertX86p32_24RGB888.L7
+
+_ConvertX86p32_24RGB888.L6:  # tail loop
+        movb (%esi),%al
+        movb 1(%esi),%bl
+        movb 2(%esi),%dl
+        movb %al,(%edi)
+        movb %bl,1(%edi)
+        movb %dl,2(%edi)
+        addl $4,%esi
+        addl $3,%edi
+        decl %ecx
+        jnz _ConvertX86p32_24RGB888.L6
+
+_ConvertX86p32_24RGB888.L7: popl %ebp
+        jmp _x86return
+
+
+
+
+## 32 bit RGB 888 to 24 bit BGR 888
+
+_ConvertX86p32_24BGR888: 
+
+        # check short
+        cmpl $32,%ecx
+        ja _ConvertX86p32_24BGR888.L3
+
+
+_ConvertX86p32_24BGR888.L1:  # short loop
+        movb (%esi),%dl
+        movb 1(%esi),%bl
+        movb 2(%esi),%al
+        movb %al,(%edi)
+        movb %bl,1(%edi)
+        movb %dl,2(%edi)
+        addl $4,%esi
+        addl $3,%edi
+        decl %ecx
+        jnz _ConvertX86p32_24BGR888.L1
+_ConvertX86p32_24BGR888.L2: 
+        jmp _x86return
+
+_ConvertX86p32_24BGR888.L3:  # head
+        movl %edi,%edx
+        andl $0b11,%edx
+        jz _ConvertX86p32_24BGR888.L4
+        movb (%esi),%dl
+        movb 1(%esi),%bl
+        movb 2(%esi),%al
+        movb %al,(%edi)
+        movb %bl,1(%edi)
+        movb %dl,2(%edi)
+        addl $4,%esi
+        addl $3,%edi
+        decl %ecx
+        jmp _ConvertX86p32_24BGR888.L3
+
+_ConvertX86p32_24BGR888.L4:  # unroll 4 times
+        pushl %ebp
+        movl %ecx,%ebp
+        shrl $2,%ebp
+
+        # save count
+        pushl %ecx
+
+_ConvertX86p32_24BGR888.L5: 
+        movl (%esi),%eax                # first dword            eax = [A][R][G][B]
+        movl 4(%esi),%ebx               # second dword           ebx = [a][r][g][b]
+
+        bswapl %eax                     #                        eax = [B][G][R][A]
+
+        bswapl %ebx                     #                        ebx = [b][g][r][a]
+
+        movb 4+2(%esi),%al              #                        eax = [B][G][R][r] 
+        movb 4+4+1(%esi),%bh            #                        ebx = [b][g][G][a]
+
+        rorl $8,%eax                    #                        eax = [r][B][G][R] (done)
+        movb 4+4+2(%esi),%bl            #                        ebx = [b][g][G][R]
+
+        rorl $16,%ebx                   #                        ebx = [G][R][b][g] (done)
+        movl %eax,(%edi)
+
+        movl %ebx,4(%edi)
+        movl 12(%esi),%ecx              # third dword            ecx = [a][r][g][b]
+
+        bswapl %ecx                     #                        ecx = [b][g][r][a]
+
+        movb 8(%esi),%cl                #                        ecx = [b][g][r][B] (done)
+        addl $4*4,%esi
+
+        movl %ecx,8(%edi)
+        addl $3*4,%edi
+
+        decl %ebp
+        jnz _ConvertX86p32_24BGR888.L5
+
+        # check tail
+        popl %ecx
+        andl $0b11,%ecx
+        jz _ConvertX86p32_24BGR888.L7
+
+_ConvertX86p32_24BGR888.L6:  # tail loop
+        movb (%esi),%dl
+        movb 1(%esi),%bl
+        movb 2(%esi),%al
+        movb %al,(%edi)
+        movb %bl,1(%edi)
+        movb %dl,2(%edi)
+        addl $4,%esi
+        addl $3,%edi
+        decl %ecx
+        jnz _ConvertX86p32_24BGR888.L6
+
+_ConvertX86p32_24BGR888.L7: 
+        popl %ebp
+        jmp _x86return
+
+
+
+
+## 32 bit RGB 888 to 16 BIT RGB 565 
+.align 8
+_ConvertX86p32_16RGB565: 
+        # check short
+        cmpl $16,%ecx
+        ja _ConvertX86p32_16RGB565.L3
+
+_ConvertX86p32_16RGB565.L1:  # short loop
+        movb (%esi),%bl   # blue
+        movb 1(%esi),%al  # green
+        movb 2(%esi),%ah  # red
+        shrb $3,%ah
+        andb $0b11111100,%al
+        shll $3,%eax
+        shrb $3,%bl
+        addb %bl,%al
+        movb %al,(%edi)
+        movb %ah,1(%edi)
+        addl $4,%esi
+        addl $2,%edi
+        decl %ecx
+        jnz _ConvertX86p32_16RGB565.L1
+
+_ConvertX86p32_16RGB565.L2:     # End of short loop
+        jmp _x86return
+
+
+_ConvertX86p32_16RGB565.L3:  # head
+        movl %edi,%ebx
+        andl $0b11,%ebx
+        jz _ConvertX86p32_16RGB565.L4
+
+        movb (%esi),%bl   # blue
+        movb 1(%esi),%al  # green
+        movb 2(%esi),%ah  # red
+        shrb $3,%ah
+        andb $0b11111100,%al
+        shll $3,%eax
+        shrb $3,%bl
+        addb %bl,%al
+        movb %al,(%edi)
+        movb %ah,1(%edi)
+        addl $4,%esi
+        addl $2,%edi
+        decl %ecx
+
+_ConvertX86p32_16RGB565.L4: 
+    # save count
+        pushl %ecx
+
+    # unroll twice
+        shrl %ecx
+
+    # point arrays to end
+        leal (%esi,%ecx,8),%esi
+        leal (%edi,%ecx,4),%edi
+
+    # negative counter 
+        negl %ecx
+        jmp _ConvertX86p32_16RGB565.L6
+
+_ConvertX86p32_16RGB565.L5: 
+        movl %eax,-4(%edi,%ecx,4)
+.align 8
+_ConvertX86p32_16RGB565.L6: 
+        movl (%esi,%ecx,8),%eax
+
+        shrb $2,%ah
+        movl 4(%esi,%ecx,8),%ebx
+
+        shrl $3,%eax
+        movl 4(%esi,%ecx,8),%edx
+
+        shrb $2,%bh
+        movb 2(%esi,%ecx,8),%dl
+
+        shll $13,%ebx
+        andl $0x000007FF,%eax
+
+        shll $8,%edx
+        andl $0x07FF0000,%ebx
+
+        andl $0x0F800F800,%edx
+        addl %ebx,%eax
+
+        addl %edx,%eax
+        incl %ecx
+
+        jnz _ConvertX86p32_16RGB565.L5
+
+        movl %eax,-4(%edi,%ecx,4)
+
+    # tail
+        popl %ecx
+        testb $1,%cl
+        jz _ConvertX86p32_16RGB565.L7
+
+        movb (%esi),%bl   # blue
+        movb 1(%esi),%al  # green
+        movb 2(%esi),%ah  # red
+        shrb $3,%ah
+        andb $0b11111100,%al
+        shll $3,%eax
+        shrb $3,%bl
+        addb %bl,%al
+        movb %al,(%edi)
+        movb %ah,1(%edi)
+        addl $4,%esi
+        addl $2,%edi
+
+_ConvertX86p32_16RGB565.L7: 
+        jmp _x86return
+
+
+
+
+## 32 bit RGB 888 to 16 BIT BGR 565 
+
+_ConvertX86p32_16BGR565: 
+
+        # check short
+        cmpl $16,%ecx
+        ja _ConvertX86p32_16BGR565.L3
+
+_ConvertX86p32_16BGR565.L1:  # short loop
+        movb (%esi),%ah   # blue
+        movb 1(%esi),%al  # green
+        movb 2(%esi),%bl  # red
+        shrb $3,%ah
+        andb $0b11111100,%al
+        shll $3,%eax
+        shrb $3,%bl
+        addb %bl,%al
+        movb %al,(%edi)
+        movb %ah,1(%edi)
+        addl $4,%esi
+        addl $2,%edi
+        decl %ecx
+        jnz _ConvertX86p32_16BGR565.L1
+_ConvertX86p32_16BGR565.L2: 
+        jmp _x86return
+
+_ConvertX86p32_16BGR565.L3:  # head
+        movl %edi,%ebx
+        andl $0b11,%ebx
+        jz _ConvertX86p32_16BGR565.L4
+        movb (%esi),%ah   # blue
+        movb 1(%esi),%al  # green
+        movb 2(%esi),%bl  # red
+        shrb $3,%ah
+        andb $0b11111100,%al
+        shll $3,%eax
+        shrb $3,%bl
+        addb %bl,%al
+        movb %al,(%edi)
+        movb %ah,1(%edi)
+        addl $4,%esi
+        addl $2,%edi
+        decl %ecx
+
+_ConvertX86p32_16BGR565.L4:  # save count
+        pushl %ecx
+
+        # unroll twice
+        shrl %ecx
+
+        # point arrays to end
+        leal (%esi,%ecx,8),%esi
+        leal (%edi,%ecx,4),%edi
+
+        # negative count
+        negl %ecx
+        jmp _ConvertX86p32_16BGR565.L6
+
+_ConvertX86p32_16BGR565.L5: 
+        movl %eax,-4(%edi,%ecx,4)
+_ConvertX86p32_16BGR565.L6: 
+        movl 4(%esi,%ecx,8),%edx
+
+        movb 4(%esi,%ecx,8),%bh
+        movb (%esi,%ecx,8),%ah
+
+        shrb $3,%bh
+        movb 1(%esi,%ecx,8),%al
+
+        shrb $3,%ah
+        movb 5(%esi,%ecx,8),%bl
+
+        shll $3,%eax
+        movb 2(%esi,%ecx,8),%dl
+
+        shll $19,%ebx
+        andl $0x0000FFE0,%eax
+
+        shrl $3,%edx
+        andl $0x0FFE00000,%ebx
+
+        andl $0x001F001F,%edx
+        addl %ebx,%eax
+
+        addl %edx,%eax
+        incl %ecx
+
+        jnz _ConvertX86p32_16BGR565.L5
+
+        movl %eax,-4(%edi,%ecx,4)
+
+        # tail
+        popl %ecx
+        andl $1,%ecx
+        jz _ConvertX86p32_16BGR565.L7
+        movb (%esi),%ah   # blue
+        movb 1(%esi),%al  # green
+        movb 2(%esi),%bl  # red
+        shrb $3,%ah
+        andb $0b11111100,%al
+        shll $3,%eax
+        shrb $3,%bl
+        addb %bl,%al
+        movb %al,(%edi)
+        movb %ah,1(%edi)
+        addl $4,%esi
+        addl $2,%edi
+
+_ConvertX86p32_16BGR565.L7: 
+        jmp _x86return
+
+
+
+
+## 32 BIT RGB TO 16 BIT RGB 555
+
+_ConvertX86p32_16RGB555: 
+
+        # check short
+        cmpl $16,%ecx
+        ja _ConvertX86p32_16RGB555.L3
+
+_ConvertX86p32_16RGB555.L1:  # short loop
+        movb (%esi),%bl   # blue
+        movb 1(%esi),%al  # green
+        movb 2(%esi),%ah  # red
+        shrb $3,%ah
+        andb $0b11111000,%al
+        shll $2,%eax
+        shrb $3,%bl
+        addb %bl,%al
+        movb %al,(%edi)
+        movb %ah,1(%edi)
+        addl $4,%esi
+        addl $2,%edi
+        decl %ecx
+        jnz _ConvertX86p32_16RGB555.L1
+_ConvertX86p32_16RGB555.L2: 
+        jmp _x86return
+
+_ConvertX86p32_16RGB555.L3:  # head
+        movl %edi,%ebx
+        andl $0b11,%ebx
+        jz _ConvertX86p32_16RGB555.L4
+        movb (%esi),%bl   # blue
+        movb 1(%esi),%al  # green
+        movb 2(%esi),%ah  # red
+        shrb $3,%ah
+        andb $0b11111000,%al
+        shll $2,%eax
+        shrb $3,%bl
+        addb %bl,%al
+        movb %al,(%edi)
+        movb %ah,1(%edi)
+        addl $4,%esi
+        addl $2,%edi
+        decl %ecx
+
+_ConvertX86p32_16RGB555.L4:  # save count
+        pushl %ecx
+
+        # unroll twice
+        shrl %ecx
+
+        # point arrays to end
+        leal (%esi,%ecx,8),%esi
+        leal (%edi,%ecx,4),%edi
+
+        # negative counter 
+        negl %ecx
+        jmp _ConvertX86p32_16RGB555.L6
+
+_ConvertX86p32_16RGB555.L5: 
+        movl %eax,-4(%edi,%ecx,4)
+_ConvertX86p32_16RGB555.L6: 
+        movl (%esi,%ecx,8),%eax
+
+        shrb $3,%ah
+        movl 4(%esi,%ecx,8),%ebx
+
+        shrl $3,%eax
+        movl 4(%esi,%ecx,8),%edx
+
+        shrb $3,%bh
+        movb 2(%esi,%ecx,8),%dl
+
+        shll $13,%ebx
+        andl $0x000007FF,%eax
+
+        shll $7,%edx
+        andl $0x07FF0000,%ebx
+
+        andl $0x07C007C00,%edx
+        addl %ebx,%eax
+
+        addl %edx,%eax
+        incl %ecx
+
+        jnz _ConvertX86p32_16RGB555.L5
+
+        movl %eax,-4(%edi,%ecx,4)
+
+        # tail
+        popl %ecx
+        andl $1,%ecx
+        jz _ConvertX86p32_16RGB555.L7
+        movb (%esi),%bl   # blue
+        movb 1(%esi),%al  # green
+        movb 2(%esi),%ah  # red
+        shrb $3,%ah
+        andb $0b11111000,%al
+        shll $2,%eax
+        shrb $3,%bl
+        addb %bl,%al
+        movb %al,(%edi)
+        movb %ah,1(%edi)
+        addl $4,%esi
+        addl $2,%edi
+
+_ConvertX86p32_16RGB555.L7: 
+        jmp _x86return
+
+
+
+
+## 32 BIT RGB TO 16 BIT BGR 555
+
+_ConvertX86p32_16BGR555: 
+
+        # check short
+        cmpl $16,%ecx
+        ja _ConvertX86p32_16BGR555.L3
+
+
+_ConvertX86p32_16BGR555.L1:  # short loop
+        movb (%esi),%ah   # blue
+        movb 1(%esi),%al  # green
+        movb 2(%esi),%bl  # red
+        shrb $3,%ah
+        andb $0b11111000,%al
+        shll $2,%eax
+        shrb $3,%bl
+        addb %bl,%al
+        movb %al,(%edi)
+        movb %ah,1(%edi)
+        addl $4,%esi
+        addl $2,%edi
+        decl %ecx
+        jnz _ConvertX86p32_16BGR555.L1
+_ConvertX86p32_16BGR555.L2: 
+        jmp _x86return
+
+_ConvertX86p32_16BGR555.L3:  # head
+        movl %edi,%ebx
+        andl $0b11,%ebx
+        jz _ConvertX86p32_16BGR555.L4
+        movb (%esi),%ah   # blue
+        movb 1(%esi),%al  # green
+        movb 2(%esi),%bl  # red
+        shrb $3,%ah
+        andb $0b11111000,%al
+        shll $2,%eax
+        shrb $3,%bl
+        addb %bl,%al
+        movb %al,(%edi)
+        movb %ah,1(%edi)
+        addl $4,%esi
+        addl $2,%edi
+        decl %ecx
+
+_ConvertX86p32_16BGR555.L4:  # save count
+        pushl %ecx
+
+        # unroll twice
+        shrl %ecx
+
+        # point arrays to end
+        leal (%esi,%ecx,8),%esi
+        leal (%edi,%ecx,4),%edi
+
+        # negative counter 
+        negl %ecx
+        jmp _ConvertX86p32_16BGR555.L6
+
+_ConvertX86p32_16BGR555.L5: 
+        movl %eax,-4(%edi,%ecx,4)
+_ConvertX86p32_16BGR555.L6: 
+        movl 4(%esi,%ecx,8),%edx
+
+        movb 4(%esi,%ecx,8),%bh
+        movb (%esi,%ecx,8),%ah
+
+        shrb $3,%bh
+        movb 1(%esi,%ecx,8),%al
+
+        shrb $3,%ah
+        movb 5(%esi,%ecx,8),%bl
+
+        shll $2,%eax
+        movb 2(%esi,%ecx,8),%dl
+
+        shll $18,%ebx
+        andl $0x00007FE0,%eax
+
+        shrl $3,%edx
+        andl $0x07FE00000,%ebx
+
+        andl $0x001F001F,%edx
+        addl %ebx,%eax
+
+        addl %edx,%eax
+        incl %ecx
+
+        jnz _ConvertX86p32_16BGR555.L5
+
+        movl %eax,-4(%edi,%ecx,4)
+
+        # tail
+        popl %ecx
+        andl $1,%ecx
+        jz _ConvertX86p32_16BGR555.L7
+        movb (%esi),%ah   # blue
+        movb 1(%esi),%al  # green
+        movb 2(%esi),%bl  # red
+        shrb $3,%ah
+        andb $0b11111000,%al
+        shll $2,%eax
+        shrb $3,%bl
+        addb %bl,%al
+        movb %al,(%edi)
+        movb %ah,1(%edi)
+        addl $4,%esi
+        addl $2,%edi
+
+_ConvertX86p32_16BGR555.L7: 
+        jmp _x86return
+
+
+
+
+
+## FROM 32 BIT RGB to 8 BIT RGB (rrrgggbbb)
+## This routine writes FOUR pixels at once (dword) and then, if they exist
+## the trailing three pixels
+_ConvertX86p32_8RGB332: 
+
+
+_ConvertX86p32_8RGB332.L_ALIGNED: 
+        pushl %ecx
+
+        shrl $2,%ecx            # We will draw 4 pixels at once
+        jnz _ConvertX86p32_8RGB332.L1
+
+        jmp _ConvertX86p32_8RGB332.L2 # short jump out of range :(
+
+_ConvertX86p32_8RGB332.L1: 
+        movl (%esi),%eax        # first pair of pixels
+        movl 4(%esi),%edx
+
+        shrb $6,%dl
+        movl %eax,%ebx
+
+        shrb $6,%al
+        andb $0x0e0,%ah
+
+        shrl $16,%ebx
+        andb $0x0e0,%dh
+
+        shrb $3,%ah
+        andb $0x0e0,%bl
+
+        shrb $3,%dh
+
+        orb %bl,%al
+
+        movl %edx,%ebx
+        orb %ah,%al
+
+        shrl $16,%ebx
+        orb %dh,%dl
+
+        andb $0x0e0,%bl
+
+        orb %bl,%dl
+
+        movb %dl,%ah
+
+
+
+        movl 8(%esi),%ebx       # second pair of pixels
+
+        movl %ebx,%edx
+        andb $0x0e0,%bh
+
+        shrb $6,%bl
+        andl $0x0e00000,%edx
+
+        shrl $16,%edx
+
+        shrb $3,%bh
+
+        rorl $16,%eax
+        orb %dl,%bl
+
+        movl 12(%esi),%edx
+        orb %bh,%bl
+
+        movb %bl,%al
+
+        movl %edx,%ebx
+        andb $0x0e0,%dh
+
+        shrb $6,%dl
+        andl $0x0e00000,%ebx
+
+        shrb $3,%dh
+        movb %dl,%ah
+
+        shrl $16,%ebx
+        orb %dh,%ah
+
+        orb %bl,%ah
+
+        roll $16,%eax
+        addl $16,%esi
+
+        movl %eax,(%edi)
+        addl $4,%edi
+
+        decl %ecx
+        jz _ConvertX86p32_8RGB332.L2 # L1 out of range for short jump :(
+
+        jmp _ConvertX86p32_8RGB332.L1
+_ConvertX86p32_8RGB332.L2: 
+
+        popl %ecx
+        andl $3,%ecx            # mask out number of pixels to draw
+
+        jz _ConvertX86p32_8RGB332.L4 # Nothing to do anymore
+
+_ConvertX86p32_8RGB332.L3: 
+        movl (%esi),%eax        # single pixel conversion for trailing pixels
+
+        movl %eax,%ebx
+
+        shrb $6,%al
+        andb $0x0e0,%ah
+
+        shrl $16,%ebx
+
+        shrb $3,%ah
+        andb $0x0e0,%bl
+
+        orb %ah,%al
+        orb %bl,%al
+
+        movb %al,(%edi)
+
+        incl %edi
+        addl $4,%esi
+
+        decl %ecx
+        jnz _ConvertX86p32_8RGB332.L3
+
+_ConvertX86p32_8RGB332.L4: 
+        jmp _x86return

+ 120 - 0
packages/hermes/src/i386/x86p_cpy.as

@@ -0,0 +1,120 @@
+
+
+
+
+
+.globl _CopyX86p_4byte
+.globl _CopyX86p_3byte
+.globl _CopyX86p_2byte
+.globl _CopyX86p_1byte
+
+.extern _x86return
+
+
+.text
+
+## _Copy*
+## Paramters:
+##   ESI = source 
+##   EDI = dest
+##   ECX = amount (NOT 0!!! (the _ConvertX86 routine checks for that though))
+## Destroys:
+##   EAX, EBX, EDX
+
+_CopyX86p_4byte: 
+
+        rep
+ movsl
+
+        jmp _x86return
+
+
+_CopyX86p_3byte: 
+
+        leal (%ecx,%ecx,2),%ecx
+        jmp _CopyX86p_1byte
+
+
+
+_CopyX86p_2byte: 
+
+        testl $3,%edi                   # Check if video memory is aligned
+        jz _CopyX86p_2byte.L_ALIGNED
+
+        movw (%esi),%ax
+        addl $2,%esi
+
+        movw %ax,(%edi)
+        addl $2,%edi
+
+        decl %ecx
+        jz _CopyX86p_2byte.L3
+
+_CopyX86p_2byte.L_ALIGNED: 
+
+        movl %ecx,%ebx                  # Save ecx for later
+
+        shrl %ecx
+        jz _CopyX86p_2byte.L2
+
+        rep
+ movsl
+
+_CopyX86p_2byte.L2: 
+        andl $1,%ebx
+        jz _CopyX86p_2byte.L3
+
+        movw (%esi),%ax
+        addl $2,%esi
+
+        movw %ax,(%edi)
+        addl $2,%edi
+
+_CopyX86p_2byte.L3: 
+        jmp _x86return
+
+
+
+_CopyX86p_1byte: 
+
+_CopyX86p_1byte.L_alignloop: 
+        testl $3,%edi
+        jz _CopyX86p_1byte.L_aligned
+
+        movb (%esi),%al
+        incl %esi
+
+        movb %al,(%edi)
+        incl %edi
+
+        decl %ecx
+        jz _CopyX86p_1byte.L4
+        jmp _CopyX86p_1byte.L_alignloop
+
+_CopyX86p_1byte.L_aligned: 
+        movl %ecx,%edx
+
+        shrl $2,%ecx
+        jz _CopyX86p_1byte.L2
+
+        rep
+ movsl
+
+_CopyX86p_1byte.L2: 
+        movl %edx,%ecx          # Get the remaining pixels to draw
+
+        andl $3,%ecx
+        jz _CopyX86p_1byte.L4   # width was modulo 4
+
+_CopyX86p_1byte.L3: 
+        movb (%esi),%al
+        incl %esi
+
+        movb %al,(%edi)
+        incl %edi
+
+        decl %ecx
+        jnz _CopyX86p_1byte.L3
+
+_CopyX86p_1byte.L4: 
+        jmp _x86return

+ 230 - 0
packages/hermes/src/i386/x86p_i8.as

@@ -0,0 +1,230 @@
+#
+# x86 format converters for HERMES
+# Copyright (c) 1998 Christian Nentwich ([email protected])
+# This source code is licensed under the GNU LGPL
+# 
+# Please refer to the file COPYING.LIB contained in the distribution for
+# licensing conditions          
+# 
+# Some routines are (c) Glenn Fiedler ([email protected]), used with permission
+#
+
+
+
+.globl _ConvertX86pI8_32
+.globl _ConvertX86pI8_24
+.globl _ConvertX86pI8_16
+
+.extern _ConvertX86
+.extern _x86return
+
+.text
+
+
+## Convert_*
+## Paramters:   
+##   ESI = source 
+##   EDI = dest
+##   ECX = amount (NOT 0!!! (the ConvertX86 routine checks for that though))
+## Destroys:
+##   EAX, EBX, EDX
+
+_ConvertX86pI8_32: 
+
+        xorl %ebx,%ebx
+        movl 36(%ebp),%edx
+_ConvertX86pI8_32.L1: 
+        movb (%esi),%bl
+        incl %esi
+
+        movl (%edx,%ebx,4),%eax
+
+        movl %eax,(%edi)
+        addl $4,%edi
+
+        decl %ecx
+        jnz _ConvertX86pI8_32.L1
+
+        jmp _x86return
+
+
+
+_ConvertX86pI8_24: 
+        movl 36(%ebp),%ebx
+
+        xorl %edx,%edx
+
+        # check short
+        cmpl $32,%ecx
+        ja _ConvertX86pI8_24.L3
+
+
+_ConvertX86pI8_24.L1:  # short loop
+        movb (%esi),%dl
+        movl (%ebx,%edx,4),%eax
+        movb %al,(%edi) # blue
+        movb %ah,1(%edi)# green
+        shrl $16,%eax
+        movb %al,2(%edi)# red
+        incl %esi
+        addl $3,%edi
+        decl %ecx
+        jnz _ConvertX86pI8_24.L1
+_ConvertX86pI8_24.L2: 
+        jmp _x86return
+
+_ConvertX86pI8_24.L3:  # head
+        movl %edi,%eax
+        andl $0b11,%eax
+        jz _ConvertX86pI8_24.L4
+        movb (%esi),%dl
+        movl (%ebx,%edx,4),%eax
+        movb %al,(%edi) # blue
+        movb %ah,1(%edi)# green
+        shrl $16,%eax
+        movb %al,2(%edi)# red
+        incl %esi
+        addl $3,%edi
+        decl %ecx
+        jmp _ConvertX86pI8_24.L3
+
+_ConvertX86pI8_24.L4:  # save ebp
+        pushl %ebp
+        movl %ebx,%ebp
+
+        # save count
+        pushl %ecx
+
+        # unroll 4 times
+        shrl $2,%ecx
+
+_ConvertX86pI8_24.L5: pushl %ecx        # save ecx
+        movb (%esi),%dl                 # index to "A"           
+
+        movl (%ebp,%edx,4),%eax         # eax = [xx][A2][A1][A0]
+        shll $8,%eax                    # eax = [A2][A1][A0][xx]
+
+        movb 1(%esi),%dl                # index to "B"
+
+        movb (%ebp,%edx,4),%al          # eax = [A2][A1][A0][B0]
+        rorl $8,%eax                    # eax = [B0][A2][A1][A0] (done)
+        movl %eax,(%edi)
+
+        movl (%ebp,%edx,4),%eax         # eax = [xx][B2][B1][B0]
+        shll $8,%eax                    # eax = [B2][B1][B0][xx]
+
+        movb 3(%esi),%dl                # index to "D"
+
+        movl (%ebp,%edx,4),%ecx         # ecx = [xx][D2][D1][D0]
+        shll $8,%ecx                    # ecx = [D2][D1][D0][xx]
+
+        movb 2(%esi),%dl                # index to "C"
+
+        movb 1(%ebp,%edx,4),%ah         # eax = [B2][B1][C1][xx]
+        movb (%ebp,%edx,4),%al          # eax = [B2][B1][C1][C0]
+        rorl $16,%eax                   # eax = [C1][C0][B2][B1] (done)
+
+        movb 2(%ebp,%edx,4),%cl         # ecx = [D2][D1][D0][C2] (done)
+
+        movl %eax,4(%edi)
+        movl %ecx,8(%edi)
+
+        addl $4,%esi
+        addl $3*4,%edi
+
+        popl %ecx                       # restore ecx
+
+        decl %ecx
+        jnz _ConvertX86pI8_24.L5
+
+        # tail
+        popl %ecx
+        andl $0b11,%ecx
+        jz _ConvertX86pI8_24.L7
+
+_ConvertX86pI8_24.L6: 
+        movb (%esi),%dl
+        movl (%ebx,%edx,4),%eax
+        movb %al,(%edi) # blue
+        movb %ah,1(%edi)# green
+        shrl $16,%eax
+        movb %al,2(%edi)# red
+        incl %esi
+        addl $3,%edi
+        decl %ecx
+        jnz _ConvertX86pI8_24.L6
+
+_ConvertX86pI8_24.L7: popl %ebp
+        jmp _x86return
+
+
+.align 8
+_ConvertX86pI8_16: 
+        xorl %ebx,%ebx
+        movl 36(%ebp),%edx
+
+        testl $3,%edi
+        jz _ConvertX86pI8_16.Laligned
+
+        movb (%esi),%bl
+
+        movl (%edx,%ebx,4),%eax
+        incl %esi
+
+        movw %ax,(%edi)
+        addl $2,%edi
+
+        decl %ecx
+        jz _ConvertX86pI8_16.out
+
+_ConvertX86pI8_16.Laligned: 
+        pushl %ecx
+
+        xorl %eax,%eax
+        xorl %ebx,%ebx
+
+        shrl %ecx
+        jz _ConvertX86pI8_16.last_pixel
+.align 8
+_ConvertX86pI8_16.Ly: 
+        movb 1(%esi),%bl
+        movb (%esi),%al
+
+        movl (%edx,%ebx,4),%ebx
+        addl $2,%esi
+
+        shll $16,%ebx
+        movl (%edx,%eax,4),%eax
+
+        orl %ebx,%eax
+        xorl %ebx,%ebx
+
+        movl %eax,(%edi)
+        addl $4,%edi
+
+        xorl %eax,%eax
+        decl %ecx
+        jnz _ConvertX86pI8_16.Ly
+
+_ConvertX86pI8_16.last_pixel: 
+        popl %ecx
+
+        testb $1,%cl
+        jz _ConvertX86pI8_16.out
+
+        movb (%esi),%bl
+
+        movl (%edx,%ebx,4),%eax
+        incl %esi
+
+        movw %ax,(%edi)
+        addl $2,%edi
+
+_ConvertX86pI8_16.out: 
+        jmp _x86return
+
+
+
+
+
+

+ 116 - 0
packages/hermes/src/i386/x86p_s32.as

@@ -0,0 +1,116 @@
+
+
+
+.globl _ConvertX86p32_16RGB565_S
+
+.text
+
+.extern _x86return_S
+
+## _Convert*_S
+## Paramters:   
+##   ESI = source
+##   EDI = dest
+##   ECX = amount (NOT 0!!! (the _ConvertX86 routine checks for that though))
+##   EDX = x increment
+## Destroys:
+##   EAX, EBX, ECX, EDX
+
+
+_ConvertX86p32_16RGB565_S: 
+
+        pushl %ebp
+        pushl %edx              # increment now at [esp+4]!
+
+        movl $0,%ebp
+
+        pushl %ecx
+        shrl %ecx
+        jnz _ConvertX86p32_16RGB565_S.L_ok
+        jmp _ConvertX86p32_16RGB565_S.L_final
+
+_ConvertX86p32_16RGB565_S.L_ok: 
+
+.align 8
+_ConvertX86p32_16RGB565_S.Lx: 
+        movl %ebp,%eax
+
+        shrl $14,%eax
+        addl 4(%esp),%ebp
+
+        movl %ebp,%edx
+        andl $0x0fffffffc,%eax
+
+        shrl $14,%edx
+        movl (%esi,%eax,),%ebx  # ebx = pixel one
+
+        andl $0x0fffffffc,%edx
+        andl $0x0f8fcf8,%ebx
+
+        shrb $2,%bh
+        movl (%esi,%edx,),%eax  # eax = pixel two
+
+        andl $0x0f8fcf8,%eax
+        addl 4(%esp),%ebp
+
+        shrb $2,%ah             # eax & ebx= rrrrr000|00gggggg|bbbbb000
+
+        movl %eax,%edx
+
+        shrw $3,%dx
+        andl $0x0f80000,%eax
+
+        shrl $8,%eax
+
+        orl %edx,%eax
+
+        shll $16,%eax
+        movl %ebx,%edx
+
+        shrw $3,%dx
+        andl $0x0f80000,%ebx
+
+        shrl $8,%ebx
+        orb %dh,%ah
+
+        orb %bh,%ah
+        orb %dl,%al
+
+        movl %eax,(%edi)
+        addl $4,%edi
+
+        decl %ecx
+        jnz _ConvertX86p32_16RGB565_S.Lx
+
+_ConvertX86p32_16RGB565_S.L_final: 
+        popl %ecx
+        andl $1,%ecx
+        jz _ConvertX86p32_16RGB565_S.L_out
+
+        shrl $14,%ebp           # trailing pixel
+
+        andl $0x0fffffffc,%ebp
+
+        movl (%esi,%ebp,),%eax
+        movl (%esi,%ebp,),%ebx
+
+        shrl $8,%ebx
+        andl $0x0fcf8,%eax
+
+        shrb $2,%ah
+        andl $0x0f800,%ebx
+
+        shrl $3,%eax
+
+        orl %ebx,%eax
+
+        movw %ax,(%edi)
+        addl $2,%edi
+
+_ConvertX86p32_16RGB565_S.L_out: 
+
+        popl %edx
+        popl %ebp
+        jmp _x86return_S
+
+

+ 42 - 0
packages/hermes/src/i386/x86pscpy.as

@@ -0,0 +1,42 @@
+
+
+
+.globl _CopyX86p_4byte_S
+.globl _CopyX86p_3byte_S
+.globl _CopyX86p_2byte_S
+.globl _CopyX86p_1byte_S
+
+.extern _x86return
+
+
+.text
+
+## _Copy*
+## Paramters:
+##   ESI = source 
+##   EDI = dest
+##   ECX = amount (NOT 0!!! (the _ConvertX86 routine checks for that though))
+## Destroys:
+##   EAX, EBX, EDX
+
+_CopyX86p_4byte_S: 
+
+
+        jmp _x86return_S
+
+
+_CopyX86p_3byte_S: 
+
+        jmp _x86return_S
+
+
+
+_CopyX86p_2byte_S: 
+
+        jmp _x86return_S
+
+_CopyX86p_1byte_S: 
+
+        jmp _x86return_S
+
+

+ 212 - 0
packages/hermes/src/list.inc

@@ -0,0 +1,212 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+Type
+  TListFreeCallback = Procedure(p : Pointer);
+  PHermesListElementStruct = ^THermesListElementStruct;
+  THermesListElementStruct = Record
+    handle : THermesHandle;
+    data : Pointer;
+    next : PHermesListElementStruct;
+  End;
+  PHermesListElement = ^THermesListElement;
+  THermesListElement = THermesListElementStruct;
+  PHermesList = ^THermesList;
+  THermesList = Record
+    first, last : PHermesListElement;
+  End;
+
+{Function Hermes_ListNew : PHermesList;
+Procedure Hermes_ListDestroy(list : PHermesList);
+Function Hermes_ListElementNew(handle : THermesHandle) : PHermesListElement;
+Procedure Hermes_ListAdd(list : PHermesList; element : PHermesListElement);
+Procedure Hermes_ListAddFront(list : PHermesList; element : PHermesListElement);
+Function Hermes_ListDeleteElement(list : PHermesList; handle : THermesHandle) : Boolean;
+Function Hermes_ListLookup(list : PHermesList;
+                           handle : THermesHandle) : PHermesListElement;}
+
+Function Hermes_ListNew : PHermesList;
+
+Var
+  tmp : PHermesList;
+
+Begin
+{  New(tmp);}
+  tmp := malloc(SizeOf(THermesList));
+  If tmp = Nil Then
+  Begin
+    Hermes_ListNew := Nil;
+    Exit;
+  End;
+  tmp^.first := Nil;
+  tmp^.last := Nil;
+  Hermes_ListNew := tmp;
+End;
+
+Procedure Hermes_ListDestroy(list : PHermesList);
+
+Var
+  tmp, run : PHermesListElement;
+
+Begin
+  If list = Nil Then
+    Exit;
+  run := list^.first;
+  While run <> Nil Do
+  Begin
+    tmp := run;
+    run := run^.next;
+    If tmp^.data <> Nil Then
+    Begin
+      {to do: free(tmp->data)}
+      free(tmp^.data);
+    End;
+    free(tmp);
+  End;
+  free(list);
+  list := Nil;
+End;
+
+Function Hermes_ListElementNew(handle : THermesHandle) : PHermesListElement;
+
+Var
+  tmp : PHermesListElement;
+
+Begin
+  tmp := malloc(SizeOf(THermesListElement));
+  If tmp = Nil Then
+  Begin
+    Hermes_ListElementNew := Nil;
+    Exit;
+  End;
+  tmp^.handle := handle;
+  tmp^.next := Nil;
+  tmp^.data := Nil;
+  Hermes_ListElementNew := tmp;
+End;
+
+Procedure Hermes_ListAdd(list : PHermesList; element : PHermesListElement);
+
+Begin
+  If (list = Nil) Or (element = Nil) Then
+    Exit;
+  If list^.first = Nil Then
+  Begin
+    list^.first := element;
+    list^.last := element;
+    element^.next := Nil;
+    Exit;
+  End;
+  list^.last^.next := element;
+  list^.last := element;
+  element^.next := Nil;
+End;
+
+Procedure Hermes_ListAddFront(list : PHermesList; element : PHermesListElement);
+
+Begin
+  If (list = Nil) Or (element = Nil) Then
+    Exit;
+  If list^.first = Nil Then
+  Begin
+    list^.first := element;
+    list^.last := element;
+    element^.next := Nil;
+    Exit;
+  End;
+  element^.next := list^.first;
+  list^.first := element;
+End;
+
+Function Hermes_ListDeleteElement(list : PHermesList; handle : THermesHandle; user_free : TListFreeCallback) : Boolean;
+
+Var
+  run, previous : PHermesListElement;
+
+Begin
+  If list = Nil Then
+  Begin
+    Hermes_ListDeleteElement := False;
+    Exit;
+  End;
+  previous := Nil;
+  run := list^.first;
+  While run <> Nil Do
+  Begin
+    If run^.handle = handle Then
+    Begin
+      If run = list^.first Then
+        list^.first := run^.next
+      Else
+        previous^.next := run^.next;
+      If run = list^.last Then
+      Begin
+        list^.last := previous;
+        If list^.last <> Nil Then
+          list^.last^.next := Nil;
+      End;
+      If run^.data <> Nil Then
+      Begin
+        If user_free <> Nil Then
+        Begin
+          user_free(run^.data);
+        End;
+        free(run^.data);
+      End;
+      free(run);
+      Hermes_ListDeleteElement := True;
+      Exit;
+    End;
+    previous := run;
+    run := run^.next;
+  End;
+  Hermes_ListDeleteElement := False;
+End;
+
+Function Hermes_ListDeleteElement(list : PHermesList; handle : THermesHandle) : Boolean;
+
+Begin
+  Hermes_ListDeleteElement := Hermes_ListDeleteElement(list, handle, Nil);
+End;
+
+Function Hermes_ListLookup(list : PHermesList;
+                           handle : THermesHandle) : PHermesListElement;
+
+Var
+  run : PHermesListElement;
+
+Begin
+  If list = Nil Then
+  Begin
+    Hermes_ListLookup := Nil;
+    Exit;
+  End;
+  run := list^.first;
+  While run <> Nil Do
+  Begin
+    If run^.handle = handle Then
+    Begin
+      Hermes_ListLookup := run;
+      Exit;
+    End;
+    run := run^.next;
+  End;
+  Hermes_ListLookup := Nil;
+End;

+ 31 - 0
packages/hermes/src/malloc.inc

@@ -0,0 +1,31 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+Function malloc(size : DWord) : Pointer;
+
+Begin
+  malloc := GetMem(size);
+End;
+
+Procedure free(ptr : Pointer);
+
+Begin
+  FreeMem(ptr);
+End;

+ 795 - 0
packages/hermes/src/p_16.inc

@@ -0,0 +1,795 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+{
+   16 bit to * converters for the HERMES library
+   Copyright (c) 1998 Christian Nentwich ([email protected])
+   This source code is licensed under the GNU LGPL
+
+   Please refer to the file COPYING.LIB contained in the distribution for
+   licensing conditions
+}
+
+{ TO 32 BIT RGB }
+Procedure ConvertP_16rgb565_32rgb888(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  d_pixel : int32;
+
+Begin
+  Repeat
+    d_pixel := Pshort16(source)^;
+
+    d_pixel := ((d_pixel And $f800) Shl 8) Or ((d_pixel And $7e0) Shl 5) Or
+               ((d_pixel And $1f) Shl 3) Or $030103;
+
+    Pint32(dest)^ := d_pixel;
+
+    Inc(source, 2);
+    Inc(dest, 4);
+    Dec(count);
+  Until count = 0;
+End;
+
+{ TO 32 BIT BGR }
+Procedure ConvertP_16rgb565_32bgr888(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  d_pixel : int32;
+
+Begin
+  Repeat
+    d_pixel := Pshort16(source)^;
+
+    d_pixel := ((d_pixel And $f800) Shr 8) Or ((d_pixel And $7e0) Shl 5) Or
+               ((d_pixel And $1f) Shl 19) Or $030103;
+
+    Pint32(dest)^ := d_pixel;
+
+    Inc(source, 2);
+    Inc(dest, 4);
+    Dec(count);
+  Until count = 0;
+End;
+
+{ TO 32 BIT RGBA }
+Procedure ConvertP_16rgb565_32rgba888(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  d_pixel : int32;
+
+Begin
+  Repeat
+    d_pixel := Pshort16(source)^;
+
+    d_pixel := ((d_pixel And $f800) Shl 8) Or ((d_pixel And $7e0) Shl 5) Or
+               ((d_pixel And $1f) Shl 3) Or $030103;
+
+    Pint32(dest)^ := (d_pixel Shl 8) Or $ff;
+
+    Inc(source, 2);
+    Inc(dest, 4);
+    Dec(count);
+  Until count = 0;
+End;
+
+{ TO 32 BIT BGRA }
+Procedure ConvertP_16rgb565_32bgra888(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  d_pixel : int32;
+
+Begin
+  Repeat
+    d_pixel := Pshort16(source)^;
+
+    d_pixel := ((d_pixel And $f800) Shr 8) Or ((d_pixel And $7e0) Shl 5) Or
+               ((d_pixel And $1f) Shl 19) Or $030103;
+
+    Pint32(dest)^ := (d_pixel Shl 8) Or $ff;
+
+    Inc(source, 2);
+    Inc(dest, 4);
+    Dec(count);
+  Until count = 0;
+End;
+
+{ TO 24 BIT RGB }
+Procedure ConvertP_16rgb565_24rgb888(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  d_pixel : int32;
+  d_ptr : Pchar8;
+
+Begin
+  d_ptr := @d_pixel;
+  Repeat
+    d_pixel := Pshort16(source)^;
+
+    d_pixel := ((d_pixel And $f800) Shl 8) Or ((d_pixel And $7e0) Shl 5) Or
+               ((d_pixel And $1f) Shl 3) Or $030103;
+
+    (dest + R_24)^ := (d_ptr + R_32)^;
+    (dest + G_24)^ := (d_ptr + G_32)^;
+    (dest + B_24)^ := (d_ptr + B_32)^;
+
+    Inc(source, 2);
+    Inc(dest, 3);
+    Dec(count);
+  Until count = 0;
+End;
+
+{ TO 24 BIT BGR }
+Procedure ConvertP_16rgb565_24bgr888(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  d_pixel : int32;
+  d_ptr : Pchar8;
+
+Begin
+  d_ptr := @d_pixel;
+  Repeat
+    d_pixel := Pshort16(source)^;
+
+    d_pixel := ((d_pixel And $f800) Shl 8) Or ((d_pixel And $7e0) Shl 5) Or
+               ((d_pixel And $1f) Shl 3) Or $030103;
+
+    { Red and blue are swapped here }
+    (dest + R_24)^ := (d_ptr + B_32)^;
+    (dest + G_24)^ := (d_ptr + G_32)^;
+    (dest + B_24)^ := (d_ptr + R_32)^;
+
+    Inc(source, 2);
+    Inc(dest, 3);
+    Dec(count);
+  Until count = 0;
+End;
+
+{ TO 16 BIT BGR 565 }
+Procedure ConvertP_16rgb565_16bgr565(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  i : DWord;
+  s_pixel : int32;
+
+Begin
+  { If we are not aligned to a dword, try and convert a single pixel }
+  If (PtrUInt(dest) And $3) <> 0 Then
+  Begin
+    s_pixel := Pshort16(source)^;
+
+    { Swap around R and B, leave G unchanged }
+    s_pixel := (s_pixel Shr 11) Or (s_pixel And $7e0) Or
+               ((s_pixel Shl 11) And $f800);
+
+    Pshort16(dest)^ := s_pixel;
+
+    Dec(count);
+    Inc(dest, 2); Inc(source, 2);
+  End;
+
+  { Now copy blocks of dwords }
+  For i := 1 To count Shr 1 Do
+  Begin
+    s_pixel := Pint32(source)^;
+
+    { Leave G unchanged, shift R to the right and B to the left }
+    s_pixel := (s_pixel And $07e007e0) Or ((s_pixel And $f800f800) Shr 11) Or
+               ((s_pixel And $001f001f) Shl 11);
+
+    Pint32(dest)^ := s_pixel;
+    Inc(source, 4); Inc(dest, 4);
+  End;
+
+  If (count And 1) <> 0 Then
+  Begin
+    s_pixel := Pshort16(source)^;
+
+    { Swap around R and B, leave G unchanged }
+    s_pixel := (s_pixel Shr 11) Or (s_pixel And $7e0) Or
+               ((s_pixel Shl 11) And $f800);
+
+    Pshort16(dest)^ := s_pixel;
+  End;
+End;
+
+{ TO 16 BIT RGB 555 }
+Procedure ConvertP_16rgb565_16rgb555(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  i : DWord;
+  s_pixel : int32;
+
+Begin
+  { If we are not aligned to a dword, try and convert a single pixel }
+  If (PtrUInt(dest) And $3) <> 0 Then
+  Begin
+    s_pixel := Pshort16(source)^;
+
+    { Leave blue untouched, mask red and shift by one, mask green and shift
+      by one }
+    s_pixel := (s_pixel And $1f) Or ((s_pixel And $f800) Shr 1) Or
+               ((s_pixel And $7c0) Shr 1);
+
+    Pshort16(dest)^ := s_pixel;
+
+    Dec(count);
+    Inc(dest, 2); Inc(source, 2);
+  End;
+
+  { Now copy blocks of dwords }
+  For i := 1 To count Shr 1 Do
+  Begin
+    s_pixel := Pint32(source)^;
+
+    { Leave blue untouched, mask red and shift by one, mask green and shift
+      by one }
+    s_pixel := (s_pixel And $001f001f) Or ((s_pixel And $f800f800) Shr 1) Or
+               ((s_pixel And $07c007c0) Shr 1);
+
+    Pint32(dest)^ := s_pixel;
+    Inc(source, 4); Inc(dest, 4);
+  End;
+
+  If (count And 1) <> 0 Then
+  Begin
+    s_pixel := Pshort16(source)^;
+
+    { Leave blue untouched, mask red and shift by one, mask green and shift
+      by one }
+    s_pixel := (s_pixel And $1f) Or ((s_pixel And $f800) Shr 1) Or
+               ((s_pixel And $7c0) Shr 1);
+
+    Pshort16(dest)^ := s_pixel;
+  End;
+End;
+
+{ TO 16 BIT BGR 555 }
+Procedure ConvertP_16rgb565_16bgr555(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  i : DWord;
+  s_pixel : int32;
+
+Begin
+  { If we are not aligned to a dword, try and convert a single pixel }
+  If (PtrUInt(dest) And $3) <> 0 Then
+  Begin
+    s_pixel := Pshort16(source)^;
+
+    { Shift red right by 11, mask green and shift right one, shift blue
+      left ten }
+    s_pixel := ((s_pixel And $f800) Shr 11) Or ((s_pixel And $7c0) Shr 1) Or
+               ((s_pixel And $1f) Shl 10);
+
+    Pshort16(dest)^ := s_pixel;
+
+    Dec(count);
+    Inc(dest, 2); Inc(source, 2);
+  End;
+
+  { Now copy blocks of dwords }
+  For i := 1 To count Shr 1 Do
+  Begin
+    s_pixel := Pint32(source)^;
+
+    { Shift red right by 11, mask green and shift right one, shift blue
+      left ten }
+    s_pixel := ((s_pixel And $f800f800) Shr 11) Or
+               ((s_pixel And $07c007c0) Shr 1) Or
+               ((s_pixel And $001f001f) Shl 10);
+
+    Pint32(dest)^ := s_pixel;
+    Inc(source, 4); Inc(dest, 4);
+  End;
+
+  If (count And 1) <> 0 Then
+  Begin
+    s_pixel := Pshort16(source)^;
+
+    { Shift red right by 11, mask green and shift right one, shift blue
+      left ten }
+    s_pixel := ((s_pixel And $f800) Shr 11) Or ((s_pixel And $7c0) Shr 1) Or
+               ((s_pixel And $1f) Shl 10);
+
+    Pshort16(dest)^ := s_pixel;
+  End;
+End;
+
+{ TO 8 BIT RGB 332 }
+Procedure ConvertP_16rgb565_8rgb332(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  s_block, d_block : int32;
+  i : DWord;
+
+Begin
+  { Align to dword first }
+  While (PtrUInt(dest) And $3) <> 0 Do
+  Begin
+    s_block := Pshort16(source)^;
+
+    s_block := ((s_block And $e000) Shr 8) Or ((s_block And $0700) Shr 6) Or
+               ((s_block And $18) Shr 3);
+
+    dest^ := s_block;
+
+    Dec(count);
+    If count = 0 Then
+      Exit;
+
+    Inc(source, 2);
+    Inc(dest);
+  End;
+
+  { Write blocks of four pixels }
+  For i := 1 To count Shr 2 Do
+  Begin
+    { Read and process first two pixels }
+    s_block := Pint32(source)^;
+
+    d_block := ((s_block And $e000e000) Shr 8) Or
+               ((s_block And $07000700) Shr 6) Or
+               ((s_block And $00180018) Shr 3);
+    d_block := (d_block And $ff) Or ((d_block And $ff0000) Shr 8);
+
+    { And the second two }
+    s_block := (Pint32(source)+1)^;
+
+    s_block := ((s_block And $e000e000) Shr 8) Or
+               ((s_block And $07000700) Shr 6) Or
+               ((s_block And $00180018) Shr 3);
+    s_block := (s_block And $ff) Or ((s_block And $ff0000) Shr 8);
+
+    { Put it all in one dword and write it }
+    d_block := d_block Or (s_block Shl 16);
+
+    Pint32(dest)^ := d_block;
+    Inc(source, 8);
+    Inc(dest, 4);
+  End;
+
+  { Clean up remaining pixels }
+  count := count And 3;
+  While count > 0 Do
+  Begin
+    Dec(count);
+    s_block := Pshort16(source)^;
+
+    dest^ := ((s_block And $e000) Shr 8) Or ((s_block And $0700) Shr 6) Or
+             ((s_block And $18) Shr 3);
+    Inc(dest);
+    Inc(source, 2);
+  End;
+End;
+
+{ -------------------------------------------------------------------------
+
+                          STRETCH CONVERTERS
+
+  ------------------------------------------------------------------------- }
+
+
+Procedure ConvertP_16rgb565_32rgb888_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x : DWord;
+  p : int32;
+
+Begin
+  x := 0;
+  Repeat
+    p := (((Pshort16(source) + (x Shr 16))^ And $f800) Shl 8) Or
+         (((Pshort16(source) + (x Shr 16))^ And $7e0) Shl 5) Or
+         (((Pshort16(source) + (x Shr 16))^ And $1f) Shl 3) Or $30103;
+
+    Inc(x, inc_source);
+
+    Pint32(dest)^ := p;
+
+    Inc(dest, 4);
+    Dec(count);
+  Until count = 0;
+End;
+
+Procedure ConvertP_16rgb565_32bgr888_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  d_pixel : int32;
+  x : DWord;
+
+Begin
+  x := 0;
+
+  Repeat
+    d_pixel := (Pshort16(source) + (x Shr 16))^;
+
+    d_pixel := ((d_pixel And $f800) Shr 8) Or ((d_pixel And $7e0) Shl 5) Or
+               ((d_pixel And $1f) Shl 19) Or $30103;
+
+    Pint32(dest)^ := d_pixel;
+
+    Inc(dest, 4);
+    Inc(x, inc_source);
+    Dec(count);
+  Until count = 0;
+End;
+
+Procedure ConvertP_16rgb565_32rgba888_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x : DWord;
+  p : int32;
+
+Begin
+  x := 0;
+  Repeat
+    p := (((Pshort16(source) + (x Shr 16))^ And $f800) Shl (8+8)) Or
+         (((Pshort16(source) + (x Shr 16))^ And $7e0) Shl (5+8)) Or
+         (((Pshort16(source) + (x Shr 16))^ And $1f) Shl (3+8)) Or $30103ff;
+
+    Inc(x, inc_source);
+
+    Pint32(dest)^ := p;
+
+    Inc(dest, 4);
+    Dec(count);
+  Until count = 0;
+End;
+
+Procedure ConvertP_16rgb565_32bgra888_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  d_pixel : int32;
+  x : DWord;
+
+Begin
+  x := 0;
+
+  Repeat
+    d_pixel := (Pshort16(source) + (x Shr 16))^;
+
+    d_pixel := ((d_pixel And $f800) {Shr 8}) Or ((d_pixel And $7e0) Shl (5+8)) Or
+               ((d_pixel And $1f) Shl (19+8)) Or $30103ff;
+
+    Pint32(dest)^ := d_pixel;
+
+    Inc(dest, 4);
+    Inc(x, inc_source);
+    Dec(count);
+  Until count = 0;
+End;
+
+Procedure ConvertP_16rgb565_24rgb888_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x : DWord;
+  p1, p2, p3, p4 : DWord;
+  c : DWord;
+
+Begin
+  x := 0;
+  While (PtrUInt(dest) And 3) <> 0 Do
+  Begin
+    p1 := (((Pshort16(source) + (x Shr 16))^ And $f800) Shl 8) Or
+          (((Pshort16(source) + (x Shr 16))^ And $7e0) Shl 5) Or
+          (((Pshort16(source) + (x Shr 16))^ And $1f) Shl 3) Or $30103;
+    Pshort16(dest)^ := p1 And $FFFF;
+    (dest + 2)^ := p1 Shr 16;
+    
+    Inc(dest, 3);
+    Inc(x, inc_source);
+    Dec(count);
+    If count = 0 Then
+      Exit;
+  End;
+  
+  c := count Shr 2;
+  While c > 0 Do
+  Begin
+    p1 := (Pshort16(source) + (x Shr 16))^;
+    p2 := (Pshort16(source) + ((x + inc_source) Shr 16))^;
+    p3 := (Pshort16(source) + ((x + 2*inc_source) Shr 16))^;
+    p4 := (Pshort16(source) + ((x + 3*inc_source) Shr 16))^;
+
+    Pint32(dest + 0)^ := ((p2 And $001F) Shl 27) Or ((p1 And $F800) Shl 8) Or ((p1 And $07E0) Shl 5) Or ((p1 And $001F) Shl 3) Or $03030103;
+    Pint32(dest + 4)^ := ((p3 And $07E0) Shl 21) Or ((p3 And $001F) Shl 19) Or (p2 And $F800) Or ((p2 And $07E0) Shr 3) Or $01030301;
+    Pint32(dest + 8)^ := ((p4 And $F800) Shl 16) Or ((p4 And $07E0) Shl 13) Or ((p4 And $001F) Shl 11) Or ((p3 And $F800) Shr 8) Or $03010303;
+    
+    Inc(x, 4*inc_source);
+    Inc(dest, 12);
+    Dec(c);
+  End;
+  
+  count := count And 3;
+  While count > 0 Do
+  Begin
+    p1 := (((Pshort16(source) + (x Shr 16))^ And $f800) Shl 8) Or
+          (((Pshort16(source) + (x Shr 16))^ And $7e0) Shl 5) Or
+          (((Pshort16(source) + (x Shr 16))^ And $1f) Shl 3) Or $30103;
+    Pshort16(dest)^ := p1 And $FFFF;
+    (dest + 2)^ := p1 Shr 16;
+    
+    Inc(dest, 3);
+    Inc(x, inc_source);
+    Dec(count);
+  End;
+End;
+
+Procedure ConvertP_16rgb565_24bgr888_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x : DWord;
+  p1, p2, p3, p4 : DWord;
+  c : DWord;
+
+Begin
+  x := 0;
+  While (PtrUInt(dest) And 3) <> 0 Do
+  Begin
+    p1 := (((Pshort16(source) + (x Shr 16))^ And $f800) Shr 8) Or
+          (((Pshort16(source) + (x Shr 16))^ And $7e0) Shl 5) Or
+          (((Pshort16(source) + (x Shr 16))^ And $1f) Shl 19) Or $30103;
+    Pshort16(dest)^ := p1 And $FFFF;
+    (dest + 2)^ := p1 Shr 16;
+    
+    Inc(dest, 3);
+    Inc(x, inc_source);
+    Dec(count);
+    If count = 0 Then
+      Exit;
+  End;
+  
+  c := count Shr 2;
+  While c > 0 Do
+  Begin
+    p1 := (Pshort16(source) + (x Shr 16))^;
+    p2 := (Pshort16(source) + ((x + inc_source) Shr 16))^;
+    p3 := (Pshort16(source) + ((x + 2*inc_source) Shr 16))^;
+    p4 := (Pshort16(source) + ((x + 3*inc_source) Shr 16))^;
+
+    Pint32(dest + 0)^ := ((p2 And $F800) Shl 16) Or ((p1 And $001F) Shl 19) Or ((p1 And $07E0) Shl 5) Or ((p1 And $F800) Shr 8) Or $03030103;
+    Pint32(dest + 4)^ := ((p3 And $07E0) Shl 21) Or ((p3 And $F800) Shl 8) Or ((p2 And $001F) Shl 11) Or ((p2 And $07E0) Shr 3) Or $01030301;
+    Pint32(dest + 8)^ := ((p4 And $001F) Shl 27) Or ((p4 And $07E0) Shl 13) Or (p4 And $F800) Or ((p3 And $001F) Shl 3) Or $03010303;
+    
+    Inc(x, 4*inc_source);
+    Inc(dest, 12);
+    Dec(c);
+  End;
+  
+  count := count And 3;
+  While count > 0 Do
+  Begin
+    p1 := (((Pshort16(source) + (x Shr 16))^ And $f800) Shr 8) Or
+          (((Pshort16(source) + (x Shr 16))^ And $7e0) Shl 5) Or
+          (((Pshort16(source) + (x Shr 16))^ And $1f) Shl 19) Or $30103;
+    Pshort16(dest)^ := p1 And $FFFF;
+    (dest + 2)^ := p1 Shr 16;
+    
+    Inc(dest, 3);
+    Inc(x, inc_source);
+    Dec(count);
+  End;
+End;
+
+Procedure ConvertP_16rgb565_16bgr565_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x, c : DWord;
+  p : int32;
+
+Begin
+  x := 0;
+  { If we are not aligned to a dword, try and convert a single pixel }
+  If (PtrUInt(dest) And $3) <> 0 Then
+  Begin
+    { Swap r and b, leave g untouched }
+    Pshort16(dest)^ := ((Pshort16(source) + (x Shr 16))^ Shr 11) Or
+                       ((Pshort16(source) + (x Shr 16))^ And $7e0) Or
+                       (((Pshort16(source) + (x Shr 16))^ Shl 11) And $f800);
+    Inc(x, inc_source);
+    Inc(dest, 2);
+    Dec(count);
+  End;
+
+  c := count Shr 1;
+  While c <> 0 Do
+  Begin
+    Dec(c);
+
+    { Swap r and b, leave g untouched }
+    p := ((Pshort16(source) + (x Shr 16))^ Shr 11) Or
+         ((Pshort16(source) + (x Shr 16))^ And $7e0) Or
+         (((Pshort16(source) + (x Shr 16))^ Shl 11) And $f800);
+    Inc(x, inc_source);
+
+    p := p Or ((((Pshort16(source) + (x Shr 16))^ Shr 11) Or
+                ((Pshort16(source) + (x Shr 16))^ And $7e0) Or
+                (((Pshort16(source) + (x Shr 16))^ Shl 11) And $f800)) Shl 16);
+    Inc(x, inc_source);
+
+    Pint32(dest)^ := p;
+    Inc(dest, 4);
+  End;
+
+  If (count And 1) <> 0 Then
+    Pshort16(dest)^ := ((Pshort16(source) + (x Shr 16))^ Shr 11) Or
+                       ((Pshort16(source) + (x Shr 16))^ And $7e0) Or
+                       (((Pshort16(source) + (x Shr 16))^ Shl 11) And $f800);
+End;
+
+Procedure ConvertP_16rgb565_16rgb555_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x, c : DWord;
+  p : int32;
+
+Begin
+  x := 0;
+  { If we are not aligned to a dword, try and convert a single pixel }
+  If (PtrUInt(dest) And $3) <> 0 Then
+  Begin
+    Pshort16(dest)^ := (((Pshort16(source) + (x Shr 16))^ And $f800) Shr 1) Or
+                       (((Pshort16(source) + (x Shr 16))^ And $7c0) Shr 1) Or
+                       ((Pshort16(source) + (x Shr 16))^ And $1f);
+    Inc(dest, 2);
+    Inc(x, inc_source);
+    Dec(count);
+  End;
+
+  c := count Shr 1;
+  While c <> 0 Do
+  Begin
+    Dec(c);
+
+    { Leave blue untouched, mask red and shift by one, mask green and shift
+      by one }
+    p := (((Pshort16(source) + (x Shr 16))^ And $f800) Shr 1) Or
+         (((Pshort16(source) + (x Shr 16))^ And $7c0) Shr 1) Or
+         ((Pshort16(source) + (x Shr 16))^ And $1f);
+    Inc(x, inc_source);
+
+    p := p Or (((((Pshort16(source) + (x Shr 16))^ And $f800) Shr 1) Or
+                (((Pshort16(source) + (x Shr 16))^ And $7c0) Shr 1) Or
+                ((Pshort16(source) + (x Shr 16))^ And $1f)) Shl 16);
+    Inc(x, inc_source);
+
+    Pint32(dest)^ := p;
+    Inc(dest, 4);
+  End;
+
+  If (count And 1) <> 0 Then
+    Pshort16(dest)^ := (((Pshort16(source) + (x Shr 16))^ And $f800) Shr 1) Or
+                       (((Pshort16(source) + (x Shr 16))^ And $7c0) Shr 1) Or
+                       ((Pshort16(source) + (x Shr 16))^ And $1f);
+End;
+
+Procedure ConvertP_16rgb565_16bgr555_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x, c : DWord;
+  p : int32;
+
+Begin
+  x := 0;
+  { If we are not aligned to a dword, try and convert a single pixel }
+  If (PtrUInt(dest) And $3) <> 0 Then
+  Begin
+    Pshort16(dest)^ := (((Pshort16(source) + (x Shr 16))^ And $f800) Shr 11) Or
+                       (((Pshort16(source) + (x Shr 16))^ And $7c0) Shr 1) Or
+                       (((Pshort16(source) + (x Shr 16))^ And $1f) Shl 10);
+    Inc(dest, 2);
+    Inc(x, inc_source);
+    Dec(count);
+  End;
+
+  c := count Shr 1;
+  While c <> 0 Do
+  Begin
+    Dec(c);
+
+    p := (((Pshort16(source) + (x Shr 16))^ And $f800) Shr 11) Or
+         (((Pshort16(source) + (x Shr 16))^ And $7c0) Shr 1) Or
+         (((Pshort16(source) + (x Shr 16))^ And $1f) Shl 10);
+    Inc(x, inc_source);
+
+    p := p Or (((((Pshort16(source) + (x Shr 16))^ And $f800) Shr 11) Or
+                (((Pshort16(source) + (x Shr 16))^ And $7c0) Shr 1) Or
+                (((Pshort16(source) + (x Shr 16))^ And $1f) Shl 10)) Shl 16);
+    Inc(x, inc_source);
+
+    Pint32(dest)^ := p;
+    Inc(dest, 4);
+  End;
+
+  If (count And 1) <> 0 Then
+    Pshort16(dest)^ := (((Pshort16(source) + (x Shr 16))^ And $f800) Shr 11) Or
+                       (((Pshort16(source) + (x Shr 16))^ And $7c0) Shr 1) Or
+                       (((Pshort16(source) + (x Shr 16))^ And $1f) Shl 10);
+End;
+
+Procedure ConvertP_16rgb565_8rgb332_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x, c : DWord;
+  p : int32;
+
+Begin
+  x := 0;
+
+  { Write single pixels until the destination address is aligned mod 4 }
+  While (PtrUInt(dest) And $3) <> 0 Do
+  Begin
+    dest^ := (((Pshort16(source) + (x Shr 16))^ Shr 8) And $e0) Or
+             (((Pshort16(source) + (x Shr 16))^ Shr 6) And $1c) Or
+             (((Pshort16(source) + (x Shr 16))^ Shr 3) And $3);
+    Inc(x, inc_source);
+    Inc(dest);
+    Dec(count);
+    If count = 0 Then
+      Exit;
+  End;
+
+
+  {* Write blocks of four pixels now }
+  c := count Shr 2;
+  While c <> 0 Do
+  Begin
+    Dec(c);
+    p := (((Pshort16(source) + (x Shr 16))^ Shr 8) And $e0) Or
+         (((Pshort16(source) + (x Shr 16))^ Shr 6) And $1c) Or
+         (((Pshort16(source) + (x Shr 16))^ Shr 3) And $3);
+    Inc(x, inc_source);
+
+    p := p Or
+      (((((Pshort16(source) + (x Shr 16))^ Shr 8) And $e0) Or
+        (((Pshort16(source) + (x Shr 16))^ Shr 6) And $1c) Or
+        (((Pshort16(source) + (x Shr 16))^ Shr 3) And $3)) Shl 8);
+    Inc(x, inc_source);
+
+    p := p Or
+      (((((Pshort16(source) + (x Shr 16))^ Shr 8) And $e0) Or
+        (((Pshort16(source) + (x Shr 16))^ Shr 6) And $1c) Or
+        (((Pshort16(source) + (x Shr 16))^ Shr 3) And $3)) Shl 16);
+    Inc(x, inc_source);
+
+    p := p Or
+      (((((Pshort16(source) + (x Shr 16))^ Shr 8) And $e0) Or
+        (((Pshort16(source) + (x Shr 16))^ Shr 6) And $1c) Or
+        (((Pshort16(source) + (x Shr 16))^ Shr 3) And $3)) Shl 24);
+    Inc(x, inc_source);
+
+    Pint32(dest)^ := p;
+
+    Inc(dest, 4);
+  End;
+
+  { Write up to three trailing pixels }
+  c := count And $3;
+  While c <> 0 Do
+  Begin
+    Dec(c);
+    dest^ := (((Pshort16(source) + (x Shr 16))^ Shr 8) And $e0) Or
+             (((Pshort16(source) + (x Shr 16))^ Shr 6) And $1c) Or
+             (((Pshort16(source) + (x Shr 16))^ Shr 3) And $3);
+    Inc(x, inc_source);
+    Inc(dest);
+  End;
+End;

+ 691 - 0
packages/hermes/src/p_24.inc

@@ -0,0 +1,691 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+{
+   Generic C converter (from 24 bit) for the HERMES library
+   Copyright (c) 1998 Christian Nentwich ([email protected])
+   This source code is licensed under the GNU LGPL
+
+   Please refer to the file COPYING.LIB contained in the distribution for
+   licensing conditions
+}
+
+{ -------------------------------------------------------------------------
+
+                             NORMAL CONVERTERS
+
+  ------------------------------------------------------------------------- }
+{ FROM 24 BIT ROUTINES }
+Procedure ConvertP_24rgb888_32rgb888(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  d_block : int32;
+
+Begin
+  Repeat
+    d_block := ((source + R_24)^ Shl 16) Or
+               ((source + G_24)^ Shl 8) Or
+               (source + B_24)^;
+    Pint32(dest)^ := d_block;
+    Inc(dest, 4);
+    Inc(source, 3);
+    Dec(count);
+  Until count = 0;
+End;
+
+Procedure ConvertP_24rgb888_32bgr888(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  d_block : int32;
+
+Begin
+  Repeat
+    d_block := (source + R_24)^ Or
+               ((source + G_24)^ Shl 8) Or
+               ((source + B_24)^ Shl 16);
+    Pint32(dest)^ := d_block;
+    Inc(dest, 4);
+    Inc(source, 3);
+    Dec(count);
+  Until count = 0;
+End;
+
+Procedure ConvertP_24rgb888_32rgba888(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  d_block : int32;
+
+Begin
+  Repeat
+    d_block := ((source + R_24)^ Shl 24) Or
+               ((source + G_24)^ Shl 16) Or
+               ((source + B_24)^ Shl 8) Or $ff;
+    Pint32(dest)^ := d_block;
+    Inc(dest, 4);
+    Inc(source, 3);
+    Dec(count);
+  Until count = 0;
+End;
+
+Procedure ConvertP_24rgb888_32bgra888(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  d_block : int32;
+
+Begin
+  Repeat
+    d_block := ((source + R_24)^ Shl 8) Or
+               ((source + G_24)^ Shl 16) Or
+               ((source + B_24)^ Shl 24) Or $ff;
+    Pint32(dest)^ := d_block;
+    Inc(dest, 4);
+    Inc(source, 3);
+    Dec(count);
+  Until count = 0;
+End;
+
+Procedure ConvertP_24rgb888_24bgr888(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  d_pix1, d_pix2, d_pix3 : int32;
+  c_pix1, c_pix2, c_pix3 : Pchar8;
+  c : DWord;
+  tmp : char8;
+
+Begin
+  While ((PtrUInt(dest) And 3) <> 0) And (count > 0) Do
+  Begin
+    (dest + 0)^ := (source + 2)^;
+    (dest + 1)^ := (source + 1)^;
+    (dest + 2)^ := (source + 0)^;
+    Dec(count);
+    Inc(dest, 3);
+    Inc(source, 3);
+  End;
+  
+  c_pix1 := @d_pix1;
+  c_pix2 := @d_pix2;
+  c_pix3 := @d_pix3;
+
+  c := count Shr 2;
+  While c > 0 Do
+  Begin
+    d_pix1 := Pint32(source)^;
+    d_pix2 := Pint32(source + 4)^;
+    d_pix3 := Pint32(source + 8)^;
+
+    { Swap R and B in all three pixels }
+    tmp := (c_pix1 + 0)^; (c_pix1 + 0)^ := (c_pix1 + 2)^; (c_pix1 + 2)^ := tmp;
+    tmp := (c_pix1 + 3)^; (c_pix1 + 3)^ := (c_pix2 + 1)^; (c_pix2 + 1)^ := tmp;
+    tmp := (c_pix2 + 2)^; (c_pix2 + 2)^ := (c_pix3 + 0)^; (c_pix3 + 0)^ := tmp;
+    tmp := (c_pix3 + 1)^; (c_pix3 + 1)^ := (c_pix3 + 3)^; (c_pix3 + 3)^ := tmp;
+
+    Pint32(dest)^ := d_pix1;
+    Pint32(dest + 4)^ := d_pix2;
+    Pint32(dest + 8)^ := d_pix3;
+    Inc(dest, 12);
+    Inc(source, 12);
+    Dec(c);
+  End;
+
+  count := count And $3;
+  While count > 0 Do
+  Begin
+    (dest + 0)^ := (source + 2)^;
+    (dest + 1)^ := (source + 1)^;
+    (dest + 2)^ := (source + 0)^;
+    Dec(count);
+    Inc(dest, 3);
+    Inc(source, 3);
+  End;
+End;
+
+Procedure ConvertP_24rgb888_16rgb565(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  d_block : int32;
+  i : DWord;
+
+Begin
+  For i := 0 To (count Shr 1) - 1 Do
+  Begin
+    d_block := (((source + R_24)^ Shl 8) And $f800) Or
+               (((source + G_24)^ Shl 3) And $7e0) Or
+               (((source + B_24)^ Shr 3) And $1f);
+
+    d_block := d_block Or
+             (((((source + R_24 + 3)^ Shl 8) And $f800) Or
+               (((source + G_24 + 3)^ Shl 3) And $7e0) Or
+               (((source + B_24 + 3)^ Shr 3) And $1f)) Shl 16);
+
+    Pint32(dest)^ := d_block;
+    Inc(source, 6);
+    Inc(dest, 4);
+  End;
+
+  If (count And 1) <> 0 Then
+  Begin
+    d_block := (((source + R_24)^ Shl 8) And $f800) Or
+               (((source + G_24)^ Shl 3) And $7e0) Or
+               (((source + B_24)^ Shr 3) And $1f);
+
+    Pshort16(dest)^ := d_block;
+  End;
+End;
+
+Procedure ConvertP_24rgb888_16bgr565(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  d_block : int32;
+  i : DWord;
+
+Begin
+  For i := 0 To (count Shr 1) - 1 Do
+  Begin
+    d_block := (((source + R_24)^ Shr 3) And $1f) Or
+               (((source + G_24)^ Shl 3) And $7e0) Or
+               (((source + B_24)^ Shl 8) And $f800);
+
+    d_block := d_block Or
+             (((((source + R_24 + 3)^ Shr 3) And $1f) Or
+               (((source + G_24 + 3)^ Shl 3) And $7e0) Or
+               (((source + B_24 + 3)^ Shl 8) And $f800)) Shl 16);
+
+    Pint32(dest)^ := d_block;
+    Inc(source, 6);
+    Inc(dest, 4);
+  End;
+
+  If (count And 1) <> 0 Then
+  Begin
+    d_block := (((source + R_24)^ Shr 3) And $1f) Or
+               (((source + G_24)^ Shl 3) And $7e0) Or
+               (((source + B_24)^ Shl 8) And $f800);
+
+    Pshort16(dest)^ := d_block;
+  End;
+End;
+
+Procedure ConvertP_24rgb888_16rgb555(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  d_block : int32;
+  i : DWord;
+
+Begin
+  For i := 0 To (count Shr 1) - 1 Do
+  Begin
+    d_block := (((source + R_24)^ Shl 7) And $7c00) Or
+               (((source + G_24)^ Shl 2) And $3e0) Or
+               (((source + B_24)^ Shr 3) And $1f);
+
+    d_block := d_block Or
+             (((((source + R_24 + 3)^ Shl 7) And $7c00) Or
+               (((source + G_24 + 3)^ Shl 2) And $3e0) Or
+               (((source + B_24 + 3)^ Shr 3) And $1f)) Shl 16);
+
+    Pint32(dest)^ := d_block;
+    Inc(source, 6);
+    Inc(dest, 4);
+  End;
+
+  If (count And 1) <> 0 Then
+  Begin
+    d_block := (((source + R_24)^ Shl 7) And $7c00) Or
+               (((source + G_24)^ Shl 2) And $3e0) Or
+               (((source + B_24)^ Shr 3) And $1f);
+
+    Pshort16(dest)^ := d_block;
+  End;
+End;
+
+Procedure ConvertP_24rgb888_16bgr555(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  d_block : int32;
+  i : DWord;
+
+Begin
+  For i := 0 To (count Shr 1) - 1 Do
+  Begin
+    d_block := (((source + R_24)^ Shr 3) And $1f) Or
+               (((source + G_24)^ Shl 2) And $3e0) Or
+               (((source + B_24)^ Shl 7) And $7c00);
+
+    d_block := d_block Or
+             (((((source + R_24 + 3)^ Shr 3) And $1f) Or
+               (((source + G_24 + 3)^ Shl 2) And $3e0) Or
+               (((source + B_24 + 3)^ Shl 7) And $7c00)) Shl 16);
+
+    Pint32(dest)^ := d_block;
+    Inc(source, 6);
+    Inc(dest, 4);
+  End;
+
+  If (count And 1) <> 0 Then
+  Begin
+    d_block := (((source + R_24)^ Shr 3) And $1f) Or
+               (((source + G_24)^ Shl 2) And $3e0) Or
+               (((source + B_24)^ Shl 7) And $7c00);
+
+    Pshort16(dest)^ := d_block;
+  End;
+End;
+
+{ optimise me !! }
+
+Procedure ConvertP_24rgb888_8rgb332(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  r, g, b : int32;
+  i : DWord;
+
+Begin
+  For i := 0 To count - 1 Do
+  Begin
+    r := (source + R_24)^ And $e0;
+    g := ((source + G_24)^ Shr 3) And $1c;
+    b := ((source + B_24)^ Shr 6) And $3;
+
+    dest^ := r Or g Or b;
+    Inc(source, 3);
+    Inc(dest);
+  End;
+End;
+
+{ -------------------------------------------------------------------------
+
+                             STRETCH CONVERTERS
+
+  ------------------------------------------------------------------------- }
+Procedure ConvertP_24rgb888_32rgb888_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x : DWord;
+
+Begin
+  x := 0;
+  Repeat
+    Pint32(dest)^ := ((source + R_24)^ Shl 16) Or
+                     ((source + G_24)^ Shl 8) Or
+                      (source + B_24)^;
+    Inc(x, inc_source);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    x := x And $FFFF;
+    Inc(dest, 4);
+    Dec(count);
+  Until count = 0;
+End;
+
+Procedure ConvertP_24rgb888_32bgr888_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x : DWord;
+
+Begin
+  x := 0;
+  Repeat
+    Pint32(dest)^ :=  (source + R_24)^ Or
+                     ((source + G_24)^ Shl 8) Or
+                     ((source + B_24)^ Shl 16);
+    Inc(x, inc_source);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    x := x And $FFFF;
+    Inc(dest, 4);
+    Dec(count);
+  Until count = 0;
+End;
+
+Procedure ConvertP_24rgb888_32rgba888_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x : DWord;
+
+Begin
+  x := 0;
+  Repeat
+    Pint32(dest)^ := ((((source + R_24)^ Shl 16) Or
+                       ((source + G_24)^ Shl 8) Or
+                        (source + B_24)^) Shl 8) Or $FF;
+    Inc(x, inc_source);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    x := x And $FFFF;
+    Inc(dest, 4);
+    Dec(count);
+  Until count = 0;
+End;
+
+Procedure ConvertP_24rgb888_32bgra888_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x : DWord;
+
+Begin
+  x := 0;
+  Repeat
+    Pint32(dest)^ :=  (((source + R_24)^ Or
+                       ((source + G_24)^ Shl 8) Or
+                       ((source + B_24)^ Shl 16)) Shl 8) Or $FF;
+    Inc(x, inc_source);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    x := x And $FFFF;
+    Inc(dest, 4);
+    Dec(count);
+  Until count = 0;
+End;
+
+Procedure ConvertP_24rgb888_24bgr888_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x : int32;
+
+Begin
+  x := 0;
+  Repeat
+    (dest + 0)^ := (source + 2)^;
+    (dest + 1)^ := (source + 1)^;
+    (dest + 2)^ := (source + 0)^;
+
+    Inc(x, inc_source);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    x := x And $FFFF;
+    Inc(dest, 3);
+    Dec(count);
+  Until count = 0;
+End;
+
+Procedure ConvertP_24rgb888_16rgb565_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  d_block : int32;
+  x : DWord;
+  c : DWord;
+
+Begin
+  x := 0;
+  If (PtrUInt(dest) And 3) <> 0 Then
+  Begin
+    d_block := (((source + R_24)^ Shl 8) And $f800) Or
+               (((source + G_24)^ Shl 3) And $7e0) Or
+               (((source + B_24)^ Shr 3) And $1f);
+
+    Inc(x, inc_source);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    x := x And $FFFF;
+
+    Pshort16(dest)^ := d_block;
+    Inc(dest, 2);
+  End;
+  c := count Shr 1;
+  While c > 0 Do
+  Begin
+    d_block := (((source + R_24)^ Shl 8) And $f800) Or
+               (((source + G_24)^ Shl 3) And $7e0) Or
+               (((source + B_24)^ Shr 3) And $1f);
+    Inc(x, inc_source);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    x := x And $FFFF;
+
+    d_block := d_block Or
+             (((((source + R_24)^ Shl 8) And $f800) Or
+               (((source + G_24)^ Shl 3) And $7e0) Or
+               (((source + B_24)^ Shr 3) And $1f)) Shl 16);
+    Inc(x, inc_source);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    x := x And $FFFF;
+
+    Pint32(dest)^ := d_block;
+    Inc(dest, 4);
+    Dec(c);
+  End;
+
+  If (count And 1) <> 0 Then
+  Begin
+    d_block := (((source + R_24)^ Shl 8) And $f800) Or
+               (((source + G_24)^ Shl 3) And $7e0) Or
+               (((source + B_24)^ Shr 3) And $1f);
+
+    Pshort16(dest)^ := d_block;
+  End;
+End;
+
+Procedure ConvertP_24rgb888_16bgr565_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  d_block : int32;
+  x : DWord;
+  c : DWord;
+
+Begin
+  x := 0;
+  If (PtrUInt(dest) And 3) <> 0 Then
+  Begin
+    d_block := (((source + R_24)^ Shr 3) And $1f) Or
+               (((source + G_24)^ Shl 3) And $7e0) Or
+               (((source + B_24)^ Shl 8) And $f800);
+
+    Inc(x, inc_source);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    x := x And $FFFF;
+
+    Pshort16(dest)^ := d_block;
+    Inc(dest, 2);
+  End;
+  c := count Shr 1;
+  While c > 0 Do
+  Begin
+    d_block := (((source + R_24)^ Shr 3) And $1f) Or
+               (((source + G_24)^ Shl 3) And $7e0) Or
+               (((source + B_24)^ Shl 8) And $f800);
+    Inc(x, inc_source);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    x := x And $FFFF;
+
+    d_block := d_block Or
+              (((((source + R_24)^ Shr 3) And $1f) Or
+                (((source + G_24)^ Shl 3) And $7e0) Or
+                (((source + B_24)^ Shl 8) And $f800)) Shl 16);
+    Inc(x, inc_source);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    x := x And $FFFF;
+
+    Pint32(dest)^ := d_block;
+    Inc(dest, 4);
+    Dec(c);
+  End;
+
+  If (count And 1) <> 0 Then
+  Begin
+    d_block := (((source + R_24)^ Shr 3) And $1f) Or
+               (((source + G_24)^ Shl 3) And $7e0) Or
+               (((source + B_24)^ Shl 8) And $f800);
+
+    Pshort16(dest)^ := d_block;
+  End;
+End;
+
+Procedure ConvertP_24rgb888_16rgb555_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  d_block : int32;
+  x : DWord;
+  c : DWord;
+
+Begin
+  x := 0;
+  If (PtrUInt(dest) And 3) <> 0 Then
+  Begin
+    d_block := (((source + R_24)^ Shl 7) And $7c00) Or
+               (((source + G_24)^ Shl 2) And $3e0) Or
+               (((source + B_24)^ Shr 3) And $1f);
+
+    Inc(x, inc_source);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    x := x And $FFFF;
+
+    Pshort16(dest)^ := d_block;
+    Inc(dest, 2);
+  End;
+  c := count Shr 1;
+  While c > 0 Do
+  Begin
+    d_block := (((source + R_24)^ Shl 7) And $7c00) Or
+               (((source + G_24)^ Shl 2) And $3e0) Or
+               (((source + B_24)^ Shr 3) And $1f);
+    Inc(x, inc_source);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    x := x And $FFFF;
+
+    d_block := d_block Or
+               (((((source + R_24)^ Shl 7) And $7c00) Or
+                (((source + G_24)^ Shl 2) And $3e0) Or
+                (((source + B_24)^ Shr 3) And $1f)) Shl 16);
+    Inc(x, inc_source);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    x := x And $FFFF;
+
+    Pint32(dest)^ := d_block;
+    Inc(dest, 4);
+    Dec(c);
+  End;
+
+  If (count And 1) <> 0 Then
+  Begin
+    d_block := (((source + R_24)^ Shl 7) And $7c00) Or
+               (((source + G_24)^ Shl 2) And $3e0) Or
+               (((source + B_24)^ Shr 3) And $1f);
+
+    Pshort16(dest)^ := d_block;
+  End;
+End;
+
+Procedure ConvertP_24rgb888_16bgr555_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  d_block : int32;
+  x : DWord;
+  c : DWord;
+
+Begin
+  x := 0;
+  If (PtrUInt(dest) And 3) <> 0 Then
+  Begin
+    d_block := (((source + R_24)^ Shr 3) And $1f) Or
+               (((source + G_24)^ Shl 2) And $3e0) Or
+               (((source + B_24)^ Shl 7) And $7c00);
+
+    Inc(x, inc_source);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    x := x And $FFFF;
+
+    Pshort16(dest)^ := d_block;
+    Inc(dest, 2);
+  End;
+  c := count Shr 1;
+  While c > 0 Do
+  Begin
+    d_block := (((source + R_24)^ Shr 3) And $1f) Or
+               (((source + G_24)^ Shl 2) And $3e0) Or
+               (((source + B_24)^ Shl 7) And $7c00);
+    Inc(x, inc_source);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    x := x And $FFFF;
+
+    d_block := d_block Or
+             (((((source + R_24)^ Shr 3) And $1f) Or
+               (((source + G_24)^ Shl 2) And $3e0) Or
+               (((source + B_24)^ Shl 7) And $7c00)) Shl 16);
+    Inc(x, inc_source);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    x := x And $FFFF;
+
+    Pint32(dest)^ := d_block;
+    Inc(dest, 4);
+    Dec(c);
+  End;
+
+  If (count And 1) <> 0 Then
+  Begin
+    d_block := (((source + R_24)^ Shr 3) And $1f) Or
+               (((source + G_24)^ Shl 2) And $3e0) Or
+               (((source + B_24)^ Shl 7) And $7c00);
+
+    Pshort16(dest)^ := d_block;
+  End;
+End;
+
+Procedure ConvertP_24rgb888_8rgb332_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  r, g, b : int32;
+  i : DWord;
+  x : DWord;
+
+Begin
+  x := 0;
+  For i := 0 To count - 1 Do
+  Begin
+    r := (source + R_24)^ And $e0;
+    g := ((source + G_24)^ Shr 3) And $1c;
+    b := ((source + B_24)^ Shr 6) And $3;
+
+    dest^ := r Or g Or b;
+    Inc(x, inc_source);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    Inc(source, x Shr 16);
+    x := x And $FFFF;
+    Inc(dest);
+  End;
+End;

+ 943 - 0
packages/hermes/src/p_32.inc

@@ -0,0 +1,943 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+{
+   32 bit to * converters for the HERMES library
+   Copyright (c) 1998 Christian Nentwich ([email protected])
+   This source code is licensed under the GNU LGPL
+
+   Please refer to the file COPYING.LIB contained in the distribution for
+   licensing conditions
+}
+
+{ -------------------------------------------------------------------------
+
+                             NORMAL CONVERTERS
+
+  ------------------------------------------------------------------------- }
+
+
+{ TO 32 BGR }
+Procedure ConvertP_32rgb888_32bgr888(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  s_pixel : int32;
+  s_ptr : Pchar8;
+  tmp : char8;
+
+Begin
+  s_ptr := @s_pixel;
+  Repeat
+    s_pixel := Pint32(source)^;
+
+    tmp := (s_ptr + R_32)^;
+    (s_ptr + R_32)^ := (s_ptr + B_32)^;
+    (s_ptr + B_32)^ := tmp;
+
+    Pint32(dest)^ := s_pixel;
+
+    Inc(dest, 4);
+    Inc(source, 4);
+    Dec(count);
+  Until count = 0;
+End;
+
+{ 32 RGBA }
+Procedure ConvertP_32rgb888_32rgba888(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Begin
+  Repeat
+    Pint32(dest)^ := (Pint32(source)^ Shl 8) Or $ff;
+
+    Inc(dest, 4);
+    Inc(source, 4);
+    Dec(count);
+  Until count = 0;
+End;
+
+{ 32 BGRA }
+Procedure ConvertP_32rgb888_32bgra888(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  s_pixel : int32;
+  s_ptr : Pchar8;
+  tmp : char8;
+
+Begin
+  s_ptr := @s_pixel;
+  Repeat
+    s_pixel := Pint32(source)^;
+
+    tmp := (s_ptr + R_32)^;
+    (s_ptr + R_32)^ := (s_ptr + B_32)^;
+    (s_ptr + B_32)^ := tmp;
+
+    Pint32(dest)^ := (s_pixel Shl 8) Or $ff;
+
+    Inc(dest, 4);
+    Inc(source, 4);
+    Dec(count);
+  Until count = 0;
+End;
+
+{ TO 24 RGB }
+Procedure ConvertP_32rgb888_24rgb888(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  s_pixel, s_pixel2 : int32;
+  s_point : Pchar8;
+  c : DWord;
+
+Begin
+  s_point := @s_pixel;
+
+  { Align mod 4 (quite important in this case.. ) }
+
+  While (PtrUInt(dest) And $3) <> 0 Do
+  Begin
+    s_pixel := Pint32(source)^;
+
+    (dest + R_24)^ := (s_point + R_32)^;
+    (dest + G_24)^ := (s_point + G_32)^;
+    (dest + B_24)^ := (s_point + B_32)^;
+
+    Inc(source, 4);
+    Inc(dest, 3);
+
+    Dec(count);
+    If count = 0 Then
+      Exit;
+  End;
+
+  { Main loop. TODO: Big endian check! }
+
+  c := count Shr 2;
+  While c <> 0 Do
+  Begin
+    Dec(c);
+    s_pixel := Pint32(source)^;
+    s_pixel2 := (Pint32(source) + 1)^;
+
+    s_pixel := (s_pixel And $ffffff) Or (s_pixel2 Shl 24);
+    Pint32(dest)^ := s_pixel;
+
+    s_pixel := (Pint32(source) + 2)^;
+    s_pixel2 := ((s_pixel2 Shr 8) And $ffff) Or (s_pixel Shl 16);
+    (Pint32(dest) + 1)^ := s_pixel2;
+
+    s_pixel2 := (Pint32(source) + 3)^;
+    s_pixel := ((s_pixel Shr 16) And $ff) Or (s_pixel2 Shl 8);
+    (Pint32(dest) + 2)^ := s_pixel;
+
+    Inc(source, 16);
+    Inc(dest, 12);
+  End;
+
+  { Convert trailing pixels }
+
+  count := count And $3;
+  While count <> 0 Do
+  Begin
+    Dec(count);
+    s_pixel := Pint32(source)^;
+
+    (dest + R_24)^ := (s_point + R_32)^;
+    (dest + G_24)^ := (s_point + G_32)^;
+    (dest + B_24)^ := (s_point + B_32)^;
+
+    Inc(source, 4);
+    Inc(dest, 3);
+  End;
+End;
+
+{ TO 24 BGR }
+Procedure ConvertP_32rgb888_24bgr888(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  s_pixel : int32;
+  s_point : Pchar8;
+
+Begin
+  s_point := @s_pixel;
+  Repeat
+    s_pixel := Pint32(source)^;
+
+    { Note that R and B are swapped }
+    (dest + B_24)^ := (s_point + R_32)^;
+    (dest + G_24)^ := (s_point + G_32)^;
+    (dest + R_24)^ := (s_point + B_32)^;
+
+    Inc(source, 4);
+    Inc(dest, 3);
+    Dec(count);
+  Until count = 0;
+End;
+
+{ TO 16 RGB 565 }
+Procedure ConvertP_32rgb888_16rgb565(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  i : DWord;
+  s_pixel : int32;
+  source_32, dest_32 : Pint32;
+
+Begin
+  dest_32 := Pint32(dest);
+  source_32 := Pint32(source);
+
+  { If the current pixel isn't dword aligned, try write one pixel first }
+  If (PtrUInt(dest_32) And $3) <> 0 Then
+  Begin
+    s_pixel := ((source_32^ Shr 8) And $f800) Or
+               ((source_32^ Shr 5) And $7e0) Or
+               ((source_32^ Shr 3) And $1f);
+
+    Pshort16(dest_32)^ := s_pixel;
+
+    dest_32 := Pint32(dest + 2);
+    Inc(source_32);
+
+    Dec(count);
+  End;
+
+  { Write blocks of two pixels }
+
+  For i := 1 To count Shr 1 Do
+  Begin
+    {This horrible construct is actually faster than loading into a variable}
+    dest_32^ := ((source_32^ Shr 8) And $f800) Or
+                ((source_32^ Shr 5) And $7e0) Or
+                ((source_32^ Shr 3) And $1f) Or
+                (((source_32 + 1)^ Shl 8) And $f8000000) Or
+                (((source_32 + 1)^ Shl 11) And $7e00000) Or
+                (((source_32 + 1)^ Shl 13) And $1f0000);
+
+    Inc(dest_32);
+    Inc(source_32, 2);
+  End;
+
+  { Eventually, write a single odd pixel that might be left }
+  If (count And 1) <> 0 Then
+  Begin
+    s_pixel := source_32^;
+    Pshort16(dest_32)^ := ((s_pixel Shr 8) And $f800) Or
+                          ((s_pixel Shr 5) And $7e0) Or
+                          ((s_pixel Shr 3) And $1f);
+  End;
+End;
+
+{ TO 16 BGR 565 }
+Procedure ConvertP_32rgb888_16bgr565(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  i : DWord;
+  r, g, b : int32;
+  s_pixel, d_pixelblock : int32;
+  d_pixel : short16;
+
+Begin
+  { If the current pixel isn't dword aligned, try write one pixel first }
+  If (PtrUInt(dest) And $3) <> 0 Then
+  Begin
+    s_pixel := Pint32(source)^;
+
+    r := (s_pixel Shr 19) And $1f;
+    g := (s_pixel Shr 5) And $7e0;
+    b := (s_pixel Shl 8) And $f800;
+
+    d_pixel := r Or g Or b;
+
+    Pshort16(dest)^ := d_pixel;
+
+    Inc(source, 4);
+    Inc(dest, 2);
+    Dec(count);
+  End;
+
+  { Write blocks of two pixels }
+  For i := 1 To count Shr 1 Do
+  Begin
+    s_pixel := Pint32(source)^;
+
+    d_pixelblock := ((s_pixel Shr 19) And $1f) Or
+                    ((s_pixel Shr 5) And $7e0) Or
+                    ((s_pixel Shl 8) And $f800);
+
+    s_pixel := (Pint32(source) + 1)^;
+
+    d_pixelblock := d_pixelblock Or
+                  ((((s_pixel Shr 19) And $1f) Or
+                    ((s_pixel Shr 5) And $7e0) Or
+                    ((s_pixel Shl 8) And $f800)) Shl 16);
+
+    Pint32(dest)^ := d_pixelblock;
+    Inc(source, 8);
+    Inc(dest, 4);
+  End;
+
+  { Eventually, write a single odd pixel that might be left }
+  If (count And 1) <> 0 Then
+  Begin
+    s_pixel := Pint32(source)^;
+
+    r := (s_pixel Shr 19) And $1f;
+    g := (s_pixel Shr 5) And $7e0;
+    b := (s_pixel Shl 8) And $f800;
+
+    d_pixel := r Or g Or b;
+
+    Pshort16(dest)^ := d_pixel;
+  End;
+End;
+
+{ TO 16 RGB 555 }
+Procedure ConvertP_32rgb888_16rgb555(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  r, g, b : int32;
+  s_pixel, d_pixelblock : int32;
+  d_pixel : short16;
+  i : DWord;
+
+Begin
+  If (PtrUInt(dest) And $3) <> 0 Then
+  Begin
+    s_pixel := Pint32(source)^;
+
+    r := (s_pixel Shr 9) And $7c00;
+    g := (s_pixel Shr 6) And $3e0;
+    b := (s_pixel Shr 3) And $1f;
+
+    d_pixel := r Or g Or b;
+
+    Pshort16(dest)^ := d_pixel;
+
+    Inc(source, 4);
+    Inc(dest, 2);
+    Dec(count);
+  End;
+
+  For i := 1 To count Shr 1 Do
+  Begin
+    s_pixel := Pint32(source)^;
+
+    d_pixelblock := ((s_pixel Shr 9) And $7c00) Or
+                    ((s_pixel Shr 6) And $3e0) Or
+                    ((s_pixel Shr 3) And $1f);
+
+    s_pixel := (Pint32(source) + 1)^;
+
+    d_pixelblock := d_pixelblock Or
+                  ((((s_pixel Shr 9) And $7c00) Or
+                    ((s_pixel Shr 6) And $3e0) Or
+                    ((s_pixel Shr 3) And $1f)) Shl 16);
+
+    Pint32(dest)^ := d_pixelblock;
+    Inc(source, 8);
+    Inc(dest, 4);
+  End;
+
+  If (count And 1) <> 0 Then
+  Begin
+    s_pixel := Pint32(source)^;
+
+    r := (s_pixel Shr 9) And $7c00;
+    g := (s_pixel Shr 6) And $3e0;
+    b := (s_pixel Shr 3) And $1f;
+
+    d_pixel := r Or g Or b;
+
+    Pshort16(dest)^ := d_pixel;
+  End;
+End;
+
+{ TO 16 BGR 555 }
+Procedure ConvertP_32rgb888_16bgr555(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  r, g, b : int32;
+  s_pixel, d_pixelblock : int32;
+  d_pixel : short16;
+  i : DWord;
+
+Begin
+  If (PtrUInt(dest) And $3) <> 0 Then
+  Begin
+    s_pixel := Pint32(source)^;
+
+    r := (s_pixel Shr 19) And $1f;
+    g := (s_pixel Shr 6) And $3e0;
+    b := (s_pixel Shl 7) And $7c00;
+
+    d_pixel := r Or g Or b;
+
+    Pshort16(dest)^ := d_pixel;
+
+    Inc(source, 4);
+    Inc(dest, 2);
+    Dec(count);
+  End;
+
+  For i := 1 To count Shr 1 Do
+  Begin
+    s_pixel := Pint32(source)^;
+
+    d_pixelblock := ((s_pixel Shr 19) And $1f) Or
+                    ((s_pixel Shr 6) And $3e0) Or
+                    ((s_pixel Shl 7) And $7c00);
+
+    s_pixel := (Pint32(source) + 1)^;
+
+    d_pixelblock := d_pixelblock Or
+                  ((((s_pixel Shr 19) And $1f) Or
+                    ((s_pixel Shr 6) And $3e0) Or
+                    ((s_pixel Shl 7) And $7c00)) Shl 16);
+
+    Pint32(dest)^ := d_pixelblock;
+    Inc(source, 8);
+    Inc(dest, 4);
+  End;
+
+  If (count And 1) <> 0 Then
+  Begin
+    s_pixel := Pint32(source)^;
+
+    r := (s_pixel Shr 19) And $1f;
+    g := (s_pixel Shr 6) And $3e0;
+    b := (s_pixel Shl 7) And $7c00;
+
+    d_pixel := r Or g Or b;
+
+    Pshort16(dest)^ := d_pixel;
+  End;
+End;
+
+{ TO 8 RGB 332 }
+Procedure ConvertP_32rgb888_8rgb332(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  i : DWord;
+  s_pixel, d_block : int32;
+  d_pixel : char8;
+
+Begin
+  { Process single pixels until we are dword aligned }
+  While (PtrUInt(dest) And $3) <> 0 Do
+  Begin
+    s_pixel := Pint32(source)^;
+
+    d_pixel := ((s_pixel Shr 16) And $e0) Or
+               ((s_pixel Shr 11) And $1c) Or
+               ((s_pixel Shr 6) And $3);
+
+    dest^ := d_pixel;
+
+    Dec(count);
+    If count = 0 Then
+      Exit;
+    Inc(dest);
+    Inc(source, 4);
+  End;
+
+  { Now process blocks of four pixels }
+  For i := 1 To count Shr 2 Do
+  Begin
+    s_pixel := Pint32(source)^;
+    d_block := ((s_pixel Shr 16) And $e0) Or
+               ((s_pixel Shr 11) And $1c) Or
+               ((s_pixel Shr 6) And $3);
+
+    s_pixel := (Pint32(source) + 1)^;
+    d_block := ((((s_pixel Shr 16) And $e0) Or
+                 ((s_pixel Shr 11) And $1c) Or
+                 ((s_pixel Shr 6) And $3)) Shl 8) Or d_block;
+
+    s_pixel := (Pint32(source) + 2)^;
+    d_block := ((((s_pixel Shr 16) And $e0) Or
+                 ((s_pixel Shr 11) And $1c) Or
+                 ((s_pixel Shr 6) And $3)) Shl 16) Or d_block;
+
+    s_pixel := (Pint32(source) + 3)^;
+    d_block := ((((s_pixel Shr 16) And $e0) Or
+                 ((s_pixel Shr 11) And $1c) Or
+                 ((s_pixel Shr 6) And $3)) Shl 24) Or d_block;
+
+    Pint32(dest)^ := d_block;
+    Inc(source, 16);
+    Inc(dest, 4);
+  End;
+
+  { Write all possibly remaining pixel }
+  count := count And $3;
+  While count <> 0 Do
+  Begin
+    Dec(count);
+    s_pixel := Pint32(source)^;
+
+    dest^ := ((s_pixel Shr 16) And $e0) Or
+             ((s_pixel Shr 11) And $1c) Or
+             ((s_pixel Shr 6) And $3);
+
+    Inc(dest);
+    Inc(source, 4);
+  End;
+End;
+
+{ -------------------------------------------------------------------------
+
+                             STRETCH CONVERTERS
+
+  ------------------------------------------------------------------------- }
+
+Procedure ConvertP_32rgb888_32bgr888_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x : DWord;
+  s_pixel : int32;
+  s_ptr : Pchar8;
+  tmp : char8;
+
+Begin
+  x := 0;
+  s_ptr := @s_pixel;
+  Repeat
+    s_pixel := (Pint32(source)+(x Shr 16))^;
+
+    tmp := (s_ptr + R_32)^;
+    (s_ptr + R_32)^ := (s_ptr + B_32)^;
+    (s_ptr + B_32)^ := tmp;
+
+    Pint32(dest)^ := s_pixel;
+
+    Inc(dest, 4);
+    Inc(x, inc_source);
+    Dec(count);
+  Until count = 0;
+End;
+
+Procedure ConvertP_32rgb888_32rgba888_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x : DWord;
+
+Begin
+  x := 0;
+  Repeat
+    Pint32(dest)^ := ((Pint32(source) + (x Shr 16))^ Shl 8) Or $ff;
+
+    Inc(dest, 4);
+    Inc(x, inc_source);
+    Dec(count);
+  Until count = 0;
+End;
+
+Procedure ConvertP_32rgb888_32bgra888_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x : DWord;
+  s_pixel : int32;
+  s_ptr : Pchar8;
+  tmp : char8;
+
+Begin
+  x := 0;
+  s_ptr := @s_pixel;
+  Repeat
+    s_pixel := (Pint32(source)+(x Shr 16))^;
+
+    tmp := (s_ptr + R_32)^;
+    (s_ptr + R_32)^ := (s_ptr + B_32)^;
+    (s_ptr + B_32)^ := tmp;
+
+    Pint32(dest)^ := (s_pixel Shl 8) Or $ff;
+
+    Inc(dest, 4);
+    Inc(x, inc_source);
+    Dec(count);
+  Until count = 0;
+End;
+
+Procedure ConvertP_32rgb888_24rgb888_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x, c : DWord;
+  s1, s2 : DWord;
+
+Begin
+  x := 0;
+  While (PtrUInt(dest) And 3) <> 0 Do
+  Begin
+    Pshort16(dest)^ := Pshort16(source)^;
+    (dest + 2)^ := (source + 2)^;
+    
+    Inc(x, inc_source);
+    Inc(source, (x Shr 16)*4);
+    x := x And $FFFF;
+    
+    Inc(dest, 3);
+    Dec(count);
+    If count = 0 Then
+      Exit;
+  End;
+  
+  c := count Shr 2;
+  While c > 0 Do
+  Begin
+    s1 := (Pint32(source) + ((x + inc_source) Shr 16))^ And $FFFFFF;
+    Pint32(dest)^ := ((Pint32(source) + (x Shr 16))^ And $FFFFFF) Or (s1 Shl 24);
+    s2 := (Pint32(source) + ((x + 2*inc_source) Shr 16))^ And $FFFFFF;
+    Pint32(dest + 4)^ := (s1 Shr 8) Or (s2 Shl 16);
+    Pint32(dest + 8)^ := (s2 Shr 16) Or ((Pint32(source) + ((x + 3*inc_source) Shr 16))^ Shl 8);
+    Inc(x, 4*inc_source);
+    
+    Inc(dest, 12);
+    Dec(c);
+  End;
+  Inc(source, (x Shr 16) * 4);
+  x := x And $FFFF;
+  
+  count := count And $3;
+  While count > 0 Do
+  Begin
+    Pshort16(dest)^ := Pshort16(source)^;
+    (dest + 2)^ := (source + 2)^;
+    
+    Inc(x, inc_source);
+    Inc(source, (x Shr 16)*4);
+    x := x And $FFFF;
+    
+    Inc(dest, 3);
+    Dec(count);
+  End;
+End;
+
+Procedure ConvertP_32rgb888_24bgr888_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x, c : DWord;
+  s1, s2, s3, s4 : DWord;
+
+Begin
+  x := 0;
+  While (PtrUInt(dest) And 3) <> 0 Do
+  Begin
+    (dest)^ := (source + 2)^;
+    (dest + 1)^ := (source + 1)^;
+    (dest + 2)^ := (source)^;
+    
+    Inc(x, inc_source);
+    Inc(source, (x Shr 16)*4);
+    x := x And $FFFF;
+    
+    Inc(dest, 3);
+    Dec(count);
+    If count = 0 Then
+      Exit;
+  End;
+  
+  c := count Shr 2;
+  While c > 0 Do
+  Begin
+    s1 := (Pint32(source) + (x Shr 16))^;
+    s2 := (Pint32(source) + ((x + inc_source) Shr 16))^;
+    s3 := (Pint32(source) + ((x + 2*inc_source) Shr 16))^;
+    s4 := (Pint32(source) + ((x + 3*inc_source) Shr 16))^;
+    
+    Pint32(dest + 0)^ := ((s2 And $FF0000) Shl 8) Or ((s1 And $FF) Shl 16) Or (s1 And $FF00) Or ((s1 Shr 16) And $FF);
+    Pint32(dest + 4)^ := ((s3 And $FF00) Shl 16) Or (s3 And $FF0000) Or ((s2 And $FF) Shl 8) Or ((s2 Shr 8) And $FF);
+    Pint32(dest + 8)^ := ((s4 And $FF) Shl 24) Or ((s4 And $FF00) Shl 8) Or ((s4 Shr 8) And $FF00) Or (s3 And $FF);
+    
+    Inc(x, 4*inc_source);
+    
+    Inc(dest, 12);
+    Dec(c);
+  End;
+  Inc(source, (x Shr 16) * 4);
+  x := x And $FFFF;
+  
+  count := count And $3;
+  While count > 0 Do
+  Begin
+    (dest)^ := (source + 2)^;
+    (dest + 1)^ := (source + 1)^;
+    (dest + 2)^ := (source)^;
+    
+    Inc(x, inc_source);
+    Inc(source, (x Shr 16)*4);
+    x := x And $FFFF;
+    
+    Inc(dest, 3);
+    Dec(count);
+  End;
+End;
+
+Procedure ConvertP_32rgb888_16rgb565_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x, c : DWord;
+  p : int32;
+
+Begin
+  x := 0;
+  { Align mod 4 }
+  If (PtrUInt(dest) And 3) <> 0 Then
+  Begin
+    Pshort16(dest)^ := (((Pint32(source) + (x Shr 16))^ Shr 8) And $f800) Or
+                       (((Pint32(source) + (x Shr 16))^ Shr 5) And $7e0) Or
+                       (((Pint32(source) + (x Shr 16))^ Shr 3) And $1f);
+    Inc(x, inc_source);
+    Inc(dest, 2);
+    Dec(count);
+  End;
+
+  { Try to write 2 pixel blocks }
+  c := count Shr 1;
+  While c <> 0 Do
+  Begin
+    Dec(c);
+    p := (((Pint32(source) + (x Shr 16))^ Shr 8) And $f800) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 5) And $7e0) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 3) And $1f);
+    Inc(x, inc_source);
+
+    p := p Or
+       (((((Pint32(source) + (x Shr 16))^ Shr 8) And $f800) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 5) And $7e0) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 3) And $1f)) Shl 16);
+    Inc(x, inc_source);
+
+    Pint32(dest)^ := p;
+
+    Inc(dest, 4);
+  End;
+
+  { Write trailing pixel }
+  If (count And 1) <> 0 Then
+    Pshort16(dest)^ := (((Pint32(source) + (x Shr 16))^ Shr 8) And $f800) Or
+                       (((Pint32(source) + (x Shr 16))^ Shr 5) And $7e0) Or
+                       (((Pint32(source) + (x Shr 16))^ Shr 3) And $1f);
+End;
+
+Procedure ConvertP_32rgb888_16bgr565_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x, c : DWord;
+  p : int32;
+
+Begin
+  x := 0;
+  { Align mod 4 }
+  If (PtrUInt(dest) And 3) <> 0 Then
+  Begin
+    Pshort16(dest)^ := (((Pint32(source) + (x Shr 16))^ Shr 19) And $1f) Or
+                       (((Pint32(source) + (x Shr 16))^ Shr 5) And $7e0) Or
+                       (((Pint32(source) + (x Shr 16))^ Shl 8) And $f800);
+    Inc(x, inc_source);
+    Inc(dest, 2);
+    Dec(count);
+  End;
+
+  { Try to write 2 pixel blocks }
+  c := count Shr 1;
+  While c <> 0 Do
+  Begin
+    Dec(c);
+    p := (((Pint32(source) + (x Shr 16))^ Shr 19) And $1f) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 5) And $7e0) Or
+         (((Pint32(source) + (x Shr 16))^ Shl 8) And $f800);
+    Inc(x, inc_source);
+
+    p := p Or
+       (((((Pint32(source) + (x Shr 16))^ Shr 19) And $1f) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 5) And $7e0) Or
+         (((Pint32(source) + (x Shr 16))^ Shl 8) And $f800)) Shl 16);
+    Inc(x, inc_source);
+
+    Pint32(dest)^ := p;
+
+    Inc(dest, 4);
+  End;
+
+  { Write trailing pixel }
+  If (count And 1) <> 0 Then
+    Pshort16(dest)^ := (((Pint32(source) + (x Shr 16))^ Shr 19) And $1f) Or
+                       (((Pint32(source) + (x Shr 16))^ Shr 5) And $7e0) Or
+                       (((Pint32(source) + (x Shr 16))^ Shl 8) And $f800);
+End;
+
+Procedure ConvertP_32rgb888_16rgb555_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x, c : DWord;
+  p : int32;
+
+Begin
+  x := 0;
+  { Align mod 4 }
+  If (PtrUInt(dest) And 3) <> 0 Then
+  Begin
+    Pshort16(dest)^ := (((Pint32(source) + (x Shr 16))^ Shr 9) And $7c00) Or
+                       (((Pint32(source) + (x Shr 16))^ Shr 6) And $3e0) Or
+                       (((Pint32(source) + (x Shr 16))^ Shr 3) And $1f);
+    Inc(x, inc_source);
+    Inc(dest, 2);
+    Dec(count);
+  End;
+
+  { Try to write 2 pixel blocks }
+  c := count Shr 1;
+  While c <> 0 Do
+  Begin
+    Dec(c);
+    p := (((Pint32(source) + (x Shr 16))^ Shr 9) And $7c00) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 6) And $3e0) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 3) And $1f);
+    Inc(x, inc_source);
+
+    p := p Or
+       (((((Pint32(source) + (x Shr 16))^ Shr 9) And $7c00) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 6) And $3e0) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 3) And $1f)) Shl 16);
+    Inc(x, inc_source);
+
+    Pint32(dest)^ := p;
+
+    Inc(dest, 4);
+  End;
+
+  { Write trailing pixel }
+  If (count And 1) <> 0 Then
+    Pshort16(dest)^ := (((Pint32(source) + (x Shr 16))^ Shr 9) And $7c00) Or
+                       (((Pint32(source) + (x Shr 16))^ Shr 6) And $3e0) Or
+                       (((Pint32(source) + (x Shr 16))^ Shr 3) And $1f);
+End;
+
+Procedure ConvertP_32rgb888_16bgr555_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x, c : DWord;
+  p : int32;
+
+Begin
+  x := 0;
+  { Align mod 4 }
+  If (PtrUInt(dest) And 3) <> 0 Then
+  Begin
+    Pshort16(dest)^ := (((Pint32(source) + (x Shr 16))^ Shr 19) And $1f) Or
+                       (((Pint32(source) + (x Shr 16))^ Shr 6) And $3e0) Or
+                       (((Pint32(source) + (x Shr 16))^ Shl 7) And $7c00);
+    Inc(x, inc_source);
+    Inc(dest, 2);
+    Dec(count);
+  End;
+
+  { Try to write 2 pixel blocks }
+  c := count Shr 1;
+  While c <> 0 Do
+  Begin
+    Dec(c);
+    p := (((Pint32(source) + (x Shr 16))^ Shr 19) And $1f) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 6) And $3e0) Or
+         (((Pint32(source) + (x Shr 16))^ Shl 7) And $7c00);
+    Inc(x, inc_source);
+
+    p := p Or
+       (((((Pint32(source) + (x Shr 16))^ Shr 19) And $1f) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 6) And $3e0) Or
+         (((Pint32(source) + (x Shr 16))^ Shl 7) And $7c00)) Shl 16);
+    Inc(x, inc_source);
+
+    Pint32(dest)^ := p;
+
+    Inc(dest, 4);
+  End;
+
+  { Write trailing pixel }
+  If (count And 1) <> 0 Then
+    Pshort16(dest)^ := (((Pint32(source) + (x Shr 16))^ Shr 19) And $1f) Or
+                       (((Pint32(source) + (x Shr 16))^ Shr 6) And $3e0) Or
+                       (((Pint32(source) + (x Shr 16))^ Shl 7) And $7c00);
+End;
+
+Procedure ConvertP_32rgb888_8rgb332_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x, c : DWord;
+  p : int32;
+
+Begin
+  x := 0;
+  { Write single pixels until the destination address is aligned mod 4 }
+  While (PtrUInt(dest) And $3) <> 0 Do
+  Begin
+    dest^ := (((Pint32(source) + (x Shr 16))^ Shr 16) And $e0) Or
+             (((Pint32(source) + (x Shr 16))^ Shr 11) And $1c) Or
+             (((Pint32(source) + (x Shr 16))^ Shr 6) And $3);
+    Inc(x, inc_source);
+    Inc(dest);
+    Dec(count);
+    If count = 0 Then
+      Exit;
+  End;
+
+  { Write blocks of four pixels now }
+  c := count Shr 2;
+  While c <> 0 Do
+  Begin
+    Dec(c);
+    p := (((Pint32(source) + (x Shr 16))^ Shr 16) And $e0) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 11) And $1c) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 6) And $3);
+    Inc(x, inc_source);
+
+    p := p Or
+       (((((Pint32(source) + (x Shr 16))^ Shr 16) And $e0) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 11) And $1c) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 6) And $3)) Shl 8);
+    Inc(x, inc_source);
+
+    p := p Or
+       (((((Pint32(source) + (x Shr 16))^ Shr 16) And $e0) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 11) And $1c) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 6) And $3)) Shl 16);
+    Inc(x, inc_source);
+
+    p := p Or
+       (((((Pint32(source) + (x Shr 16))^ Shr 16) And $e0) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 11) And $1c) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 6) And $3)) Shl 24);
+    Inc(x, inc_source);
+
+    Pint32(dest)^ := p;
+    Inc(dest, 4);
+  End;
+
+  { Write up to three trailing pixels }
+  c := count And $3;
+  While c <> 0 Do
+  Begin
+    Dec(c);
+    dest^ := (((Pint32(source) + (x Shr 16))^ Shr 16) And $e0) Or
+             (((Pint32(source) + (x Shr 16))^ Shr 11) And $1c) Or
+             (((Pint32(source) + (x Shr 16))^ Shr 6) And $3);
+    Inc(x, inc_source);
+    Inc(dest);
+  End;
+End;

+ 171 - 0
packages/hermes/src/p_clr.inc

@@ -0,0 +1,171 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+{
+   C surface clearing routines for the HERMES library
+   Copyright (c) 1998 Christian Nentwich ([email protected])
+   This source code is licensed under the GNU LGPL
+
+   Please refer to the file COPYING.LIB contained in the distribution for
+   licensing conditions
+}
+
+Procedure ClearP_32(iface : PHermesClearInterface); CDecl;
+
+Var
+  count : DWord;
+  value : int32;
+  dest : Pchar8;
+
+Begin
+  value := iface^.value;
+  dest := iface^.dest;
+  Repeat
+    count := iface^.width;
+    Repeat
+      Pint32(dest)^ := value;
+      Inc(dest, 4);
+      Dec(count);
+    Until count = 0;
+    Inc(dest, iface^.add);
+    Dec(iface^.height);
+  Until iface^.height = 0;
+End;
+
+Procedure ClearP_24(iface : PHermesClearInterface); CDecl;
+
+Var
+  p_value : Pchar8;
+  count : DWord;
+  dest : Pchar8;
+
+Begin
+  p_value := @iface^.value;
+  dest := iface^.dest;
+  Repeat
+    count := iface^.width;
+    Repeat
+      (dest + R_24)^ := (p_value + B_32)^;
+      (dest + G_24)^ := (p_value + G_32)^;
+      (dest + B_24)^ := (p_value + B_32)^;
+
+      Inc(dest, 3);
+      Dec(count);
+    Until count = 0;
+
+    Inc(dest, iface^.add);
+    Dec(iface^.height);
+  Until iface^.height = 0;
+End;
+
+Procedure ClearP_16(iface : PHermesClearInterface); CDecl;
+
+Var
+  value32 : DWord;
+  countshifted, count : DWord;
+  dest : Pchar8;
+
+Begin
+  value32 := (iface^.value Shl 16) Or (iface^.value And $ffff);
+  dest := iface^.dest;
+  Repeat
+    count := iface^.width;
+
+    { Align destination }
+    If (PtrUInt(dest) And $3) <> 0 Then
+    Begin
+      Pshort16(dest)^ := iface^.value;
+      Inc(dest, 2);
+      Dec(count);
+    End;
+
+    countshifted := count Shr 1;
+
+    While countshifted <> 0 Do
+    Begin
+      Dec(countshifted);
+      Pint32(dest)^ := value32;
+      Inc(dest, 4);
+    End;
+
+    If (count And 1) <> 0 Then
+    Begin
+      Pshort16(dest)^ := iface^.value;
+      Inc(dest, 2);
+    End;
+
+    Inc(dest, iface^.add);
+    Dec(iface^.height);
+  Until iface^.height = 0;
+End;
+
+{$GOTO ON}
+
+Procedure ClearP_8(iface : PHermesClearInterface); CDecl;
+
+Label
+  yloop;
+
+Var
+  count, shiftcount : DWord;
+  value32 : int32;
+  value : char8;
+  dest : Pchar8;
+
+Begin
+  dest := iface^.dest;
+
+  value := iface^.value And $ff;
+  value32 := (value Shl 24) Or (value Shl 16) Or (value Shl 8) Or value;
+
+  Repeat
+    count := iface^.width;
+
+    While (PtrUInt(dest) And $3) <> 0 Do    { Align to dword boundary }
+    Begin
+      dest^ := value;
+      Inc(dest);
+      Dec(count);
+      If count = 0 Then
+        Goto yloop;                { GOTO's are nice ;) }
+    End;
+
+    shiftcount := count Shr 2;
+
+    While shiftcount <> 0 Do
+    Begin
+      Dec(shiftcount);
+      Pint32(dest)^ := value32;
+      Inc(dest, 4);
+    End;
+
+    count := count And $3;
+    While count <> 0 Do
+    Begin
+      Dec(count);
+      dest^ := value;
+      Inc(dest);
+    End;
+
+yloop:
+    Inc(dest, iface^.add);
+    Dec(iface^.height);
+  Until iface^.height = 0;
+End;

+ 67 - 0
packages/hermes/src/p_cnv.inc

@@ -0,0 +1,67 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+{
+   C converter main loops for the HERMES library
+   Copyright (c) 1998 Christian Nentwich ([email protected])
+   This source code is licensed under the GNU LGPL
+
+   Please refer to the file COPYING.LIB contained in the distribution for
+   licensing conditions
+}
+
+Procedure ConvertP(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  { Simply loop through all scanlines }
+  Repeat
+    iface^.func(iface^.s_pixels, iface^.d_pixels, iface^.d_width, 1);
+
+    Inc(iface^.s_pixels, iface^.s_pitch);
+    Inc(iface^.d_pixels, iface^.d_pitch);
+    Dec(iface^.d_height);
+  Until iface^.d_height = 0;
+End;
+
+Procedure ConvertPStretch(iface : PHermesConverterInterface); CDecl;
+
+Var
+  dx, dy : DWord;
+  y : DWord;
+
+Begin
+  y := 0;
+  dy := (iface^.s_height Shl 16) Div iface^.d_height;
+  dx := (iface^.s_width Shl 16) Div iface^.d_width;
+
+  { We have the increment of y and x on the source surface now let's start }
+  Repeat
+    iface^.func(iface^.s_pixels, iface^.d_pixels, iface^.d_width, dx);
+
+    Inc(iface^.d_pixels, iface^.d_pitch);
+
+    Inc(y, dy);
+
+    { Check how many lines we need to step forward }
+    Inc(iface^.s_pixels, (y Shr 16)*DWord(iface^.s_pitch));
+    y := y And $ffff;
+    Dec(iface^.d_height);
+  Until iface^.d_height = 0;
+End;

+ 167 - 0
packages/hermes/src/p_cpy.inc

@@ -0,0 +1,167 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+{
+   C straight copy routines for the HERMES library
+   Copyright (c) 1998 Christian Nentwich ([email protected])
+   This source code is licensed under the GNU LGPL
+
+   Please refer to the file COPYING.LIB contained in the distribution for
+   licensing conditions
+}
+
+Procedure CopyP_4byte(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Begin
+  Move(source^, dest^, count Shl 2);
+End;
+
+Procedure CopyP_3byte(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Begin
+  Move(source^, dest^, count * 3);
+End;
+
+Procedure CopyP_2byte(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Begin
+  Move(source^, dest^, count Shl 1);
+End;
+
+Procedure CopyP_1byte(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Begin
+  Move(source^, dest^, count);
+End;
+
+Procedure CopyP_4byte_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x : DWord;
+
+Begin
+  x := 0;
+  Repeat
+    Pint32(dest)^ := (Pint32(source)+(x Shr 16))^;
+
+    Inc(x, inc_source);
+    Inc(dest, 4);
+    Dec(count);
+  Until count = 0;
+End;
+
+{ TODO: Optimise }
+Procedure CopyP_3byte_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x : DWord;
+
+Begin
+  x := 0;
+  Repeat
+    dest[R_24] := source[R_24];
+    dest[G_24] := source[G_24];
+    dest[B_24] := source[B_24];
+
+    Inc(x, inc_source);
+    Inc(source, 3*(x Shr 16));
+    x := x And $FFFF;
+    Inc(dest, 3);
+    Dec(count);
+  Until count = 0;
+End;
+
+Procedure CopyP_2byte_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x, c : DWord;
+  p : int32;
+
+Begin
+  x := 0;
+  { Alignment mod 4 }
+  If (PtrUInt(dest) And 3) <> 0 Then
+  Begin
+    Pshort16(dest)^ := (Pshort16(source) + (x Shr 16))^;
+    Inc(x, inc_source);
+    Inc(dest, 2);
+    Dec(count);
+  End;
+
+  c := count Shr 1;
+
+  While c <> 0 Do
+  Begin
+    Dec(c);
+    { TODO: make fast :) }
+    p := (Pshort16(source) + (x Shr 16))^; Inc(x, inc_source);
+    p := p Or ((Pshort16(source) + (x Shr 16))^ Shl 16);
+    Inc(x, inc_source);
+
+    Pint32(dest)^ := p;
+    Inc(dest, 4);
+  End;
+
+  If (count And 1) <> 0 Then
+    Pshort16(dest)^ := (Pshort16(source) + (x Shr 16))^;
+End;
+
+Procedure CopyP_1byte_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x, c : DWord;
+  p : int32;
+
+Begin
+  x := 0;
+  { Alignment mod 4 }
+  While (PtrUInt(dest) And 3) <> 0 Do
+  Begin
+    dest^ := (source + (x Shr 16))^;
+    Inc(x, inc_source);
+    Inc(dest); Dec(count);
+    If count = 0 Then
+      Exit;
+  End;
+
+  { Write blocks of four pixels }
+  c := count Shr 2;
+  While c <> 0 Do
+  Begin
+    Dec(c);
+    p := (source + (x Shr 16))^; Inc(x, inc_source);
+    p := p Or ((source + (x Shr 16))^ Shl 8); Inc(x, inc_source);
+    p := p Or ((source + (x Shr 16))^ Shl 16); Inc(x, inc_source);
+    p := p Or ((source + (x Shr 16))^ Shl 24); Inc(x, inc_source);
+
+    Pint32(dest)^ := p;
+    Inc(dest, 4);
+  End;
+
+  { Write up to three trailing pixels }
+  c := count And $3;
+  While c <> 0 Do
+  Begin
+    Dec(c);
+    dest^ := (source + (x Shr 16))^;
+    Inc(x, inc_source);
+    Inc(dest);
+  End;
+End;

+ 1118 - 0
packages/hermes/src/p_g.inc

@@ -0,0 +1,1118 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+{
+   Generic format conversion routines for the HERMES library
+   Copyright (c) 1998 Christian Nentwich ([email protected])
+   This source code is licensed under the GNU LGPL
+
+   Please refer to the file COPYING.LIB contained in the distribution for
+   licensing conditions
+}
+
+Procedure ConvertP_Generic32_Generic32(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b : int32;
+  count : DWord;
+  source, dest : Pchar8;
+
+Begin
+  source := iface^.s_pixels; dest := iface^.d_pixels;
+  Repeat
+    count := iface^.s_width;
+    Repeat
+      s_pixel := Pint32(source)^;
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+
+      Pint32(dest)^ := r Or g Or b;
+
+      Inc(source, 4);
+      Inc(dest, 4);
+      Dec(count);
+    Until count = 0;
+
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+    Dec(iface^.s_height);
+  Until iface^.s_height = 0;
+End;
+
+Procedure ConvertP_Generic32_Generic24(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b : int32;
+  d_ptr : Pchar8;
+  count : DWord;
+  source, dest : Pchar8;
+
+Begin
+  d_ptr := @s_pixel;
+  source := iface^.s_pixels; dest := iface^.d_pixels;
+  Repeat
+    count := iface^.s_width;
+    Repeat
+      s_pixel := Pint32(source)^;
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+
+      s_pixel := r Or g Or b;
+
+      (dest+R_24)^ := (d_ptr+R_32)^;
+      (dest+G_24)^ := (d_ptr+G_32)^;
+      (dest+B_24)^ := (d_ptr+B_32)^;
+
+      Inc(source, 4);
+      Inc(dest, 3);
+      Dec(count);
+    Until count = 0;
+
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+    Dec(iface^.s_height);
+  Until iface^.s_height = 0;
+End;
+
+Procedure ConvertP_Generic32_Generic16(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b : int32;
+  count : DWord;
+  source, dest : Pchar8;
+
+Begin
+  source := iface^.s_pixels; dest := iface^.d_pixels;
+  Repeat
+    count := iface^.s_width Shr 1;
+
+    If count <> 0 Then
+      Repeat
+        r := (((Pint32(source)^) Shr iface^.info.r_right) Shl iface^.info.r_left) And
+              iface^.mask_r;
+        g := (((Pint32(source)^) Shr iface^.info.g_right) Shl iface^.info.g_left) And
+              iface^.mask_g;
+        b := (((Pint32(source)^) Shr iface^.info.b_right) Shl iface^.info.b_left) And
+              iface^.mask_b;
+
+        s_pixel := (r Or g Or b) And $FFFF;
+
+        r := ((((Pint32(source)+1)^) Shr iface^.info.r_right) Shl iface^.info.r_left) And
+              iface^.mask_r;
+        g := ((((Pint32(source)+1)^) Shr iface^.info.g_right) Shl iface^.info.g_left) And
+              iface^.mask_g;
+        b := ((((Pint32(source)+1)^) Shr iface^.info.b_right) Shl iface^.info.b_left) And
+              iface^.mask_b;
+
+        s_pixel := s_pixel Or ((r Or g Or b) Shl 16);
+
+        Pint32(dest)^ := s_pixel;
+
+        Inc(source, 8);
+        Inc(dest, 4);
+        Dec(count);
+      Until count = 0;
+
+
+    { Trailing pixel }
+
+    If (iface^.s_width And 1) <> 0 Then
+    Begin
+      r := (((Pint32(source)^) Shr iface^.info.r_right) Shl iface^.info.r_left) And
+            iface^.mask_r;
+      g := (((Pint32(source)^) Shr iface^.info.g_right) Shl iface^.info.g_left) And
+            iface^.mask_g;
+      b := (((Pint32(source)^) Shr iface^.info.b_right) Shl iface^.info.b_left) And
+            iface^.mask_b;
+
+      Pshort16(dest)^ := r Or g Or b;
+      Inc(dest, 2);
+      Inc(source, 4);
+    End;
+
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+    Dec(iface^.s_height);
+  Until iface^.s_height = 0;
+End;
+
+Procedure ConvertP_Generic32_Generic8(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b : int32;
+  count : DWord;
+  source, dest : Pchar8;
+
+Begin
+  source := iface^.s_pixels; dest := iface^.d_pixels;
+  Repeat
+    count := iface^.s_width;
+    Repeat
+      s_pixel := Pint32(source)^;
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+
+      dest^ := r Or g Or b;
+
+      Inc(source, 4);
+      Inc(dest);
+      Dec(count);
+    Until count = 0;
+
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+    Dec(iface^.s_height);
+  Until iface^.s_height = 0;
+End;
+
+Procedure ConvertP_Generic24_Generic32(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b : int32;
+  count : DWord;
+  source, dest : Pchar8;
+
+Begin
+  source := iface^.s_pixels; dest := iface^.d_pixels;
+  Repeat
+    count := iface^.s_width;
+    Repeat
+      s_pixel := (((source+R_24)^) Shl 16) Or
+                 (((source+G_24)^) Shl 8) Or
+                 ((source+B_24)^);
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+
+      Pint32(dest)^ := r Or g Or b;
+
+      Inc(source, 3);
+      Inc(dest, 4);
+      Dec(count);
+    Until count = 0;
+
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+    Dec(iface^.s_height);
+  Until iface^.s_height = 0;
+End;
+
+Procedure ConvertP_Generic24_Generic24(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b : int32;
+  d_ptr : Pchar8;
+  count : DWord;
+  source, dest : PChar8;
+
+Begin
+  d_ptr := @s_pixel;
+  source := iface^.s_pixels; dest := iface^.d_pixels;
+  Repeat
+    count := iface^.s_width;
+    Repeat
+      s_pixel := (((source+R_24)^) Shl 16) Or
+                 (((source+G_24)^) Shl 8) Or
+                 ((source+B_24)^);
+
+      r := ((s_pixel Shl iface^.info.r_left) Shr iface^.info.r_right) And
+        iface^.mask_r;
+      g := ((s_pixel Shl iface^.info.g_left) Shr iface^.info.g_right) And
+        iface^.mask_g;
+      b := ((s_pixel Shl iface^.info.b_left) Shr iface^.info.b_right) And
+        iface^.mask_b;
+
+      s_pixel := r Or g Or b;
+
+      (dest + R_24)^ := (d_ptr + R_32)^;
+      (dest + G_24)^ := (d_ptr + G_32)^;
+      (dest + B_24)^ := (d_ptr + B_32)^;
+
+      Inc(source, 3);
+      Inc(dest, 3);
+      Dec(count);
+    Until count = 0;
+
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+    Dec(iface^.s_height);
+  Until iface^.s_height = 0;
+End;
+
+Procedure ConvertP_Generic24_Generic16(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b : int32;
+  count : DWord;
+  source, dest : Pchar8;
+
+Begin
+  source := iface^.s_pixels; dest := iface^.d_pixels;
+  Repeat
+    count := iface^.s_width;
+    Repeat
+      s_pixel := (((source+R_24)^) Shl 16) Or
+                 (((source+G_24)^) Shl 8) Or
+                 ((source+B_24)^);
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+
+      Pshort16(dest)^ := r Or g Or b;
+
+      Inc(source, 3);
+      Inc(dest, 2);
+      Dec(count);
+    Until count = 0;
+
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+    Dec(iface^.s_height);
+  Until iface^.s_height = 0;
+End;
+
+Procedure ConvertP_Generic24_Generic8(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b : int32;
+  count : DWord;
+  source, dest : Pchar8;
+
+Begin
+  source := iface^.s_pixels; dest := iface^.d_pixels;
+  Repeat
+    count := iface^.s_width;
+    Repeat
+      s_pixel := (((source+R_24)^) Shl 16) Or
+                 (((source+G_24)^) Shl 8) Or
+                 ((source+B_24)^);
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+
+      dest^ := r Or g Or b;
+
+      Inc(source, 3);
+      Inc(dest);
+      Dec(count);
+    Until count = 0;
+
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+    Dec(iface^.s_height);
+  Until iface^.s_height = 0;
+End;
+
+Procedure ConvertP_Generic16_Generic32(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b : int32;
+  count : DWord;
+  source, dest : Pchar8;
+
+Begin
+  source := iface^.s_pixels; dest := iface^.d_pixels;
+  Repeat
+    count := iface^.s_width;
+    Repeat
+      s_pixel := Pshort16(source)^;
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+
+      Pint32(dest)^ := r Or g Or b;
+
+      Inc(source, 2);
+      Inc(dest, 4);
+      Dec(count);
+    Until count = 0;
+
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+    Dec(iface^.s_height);
+  Until iface^.s_height = 0;
+End;
+
+Procedure ConvertP_Generic16_Generic24(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b : int32;
+  d_ptr : Pchar8;
+  count : DWord;
+  source, dest : Pchar8;
+
+Begin
+  d_ptr := @s_pixel;
+  source := iface^.s_pixels; dest := iface^.d_pixels;
+  Repeat
+    count := iface^.s_width;
+    Repeat
+      s_pixel := Pshort16(source)^;
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+
+      s_pixel := r Or g Or b;
+
+      (dest + R_24)^ := (d_ptr + R_32)^;
+      (dest + G_24)^ := (d_ptr + G_32)^;
+      (dest + B_24)^ := (d_ptr + B_32)^;
+
+      Inc(source, 2);
+      Inc(dest, 3);
+      Dec(count);
+    Until count = 0;
+
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+    Dec(iface^.s_height);
+  Until iface^.s_height = 0;
+End;
+
+Procedure ConvertP_Generic16_Generic16(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b : int32;
+  count : DWord;
+  source, dest : Pchar8;
+
+Begin
+  source := iface^.s_pixels; dest := iface^.d_pixels;
+  Repeat
+    count := iface^.s_width;
+    Repeat
+      s_pixel := Pshort16(source)^;
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+
+      Pshort16(dest)^ := r Or g Or b;
+
+      Inc(source, 2);
+      Inc(dest, 2);
+      Dec(count);
+    Until count = 0;
+
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+    Dec(iface^.s_height);
+  Until iface^.s_height = 0;
+End;
+
+Procedure ConvertP_Generic16_Generic8(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b : int32;
+  count : DWord;
+  source, dest : Pchar8;
+
+Begin
+  source := iface^.s_pixels; dest := iface^.d_pixels;
+  Repeat
+    count := iface^.s_width;
+    Repeat
+      s_pixel := Pshort16(source)^;
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+
+      dest^ := r Or g Or b;
+
+      Inc(source, 2);
+      Inc(dest);
+      Dec(count);
+    Until count = 0;
+
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+    Dec(iface^.s_height);
+  Until iface^.s_height = 0;
+End;
+
+Procedure ConvertP_Generic8_Generic32(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {todo}
+End;
+
+Procedure ConvertP_Generic8_Generic24(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {todo}
+End;
+
+Procedure ConvertP_Generic8_Generic16(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {todo}
+End;
+
+Procedure ConvertP_Generic8_Generic8(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {todo}
+End;
+
+{ -------------------------------------------------------------------------
+
+                              STRETCH CONVERTERS
+
+  ------------------------------------------------------------------------- }
+
+Procedure ConvertP_Generic32_Generic32_S(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b : int32;
+  count : DWord;
+  source, dest : Pchar8;
+  dx, dy, x, y : DWord;
+
+Begin
+  source := iface^.s_pixels;
+  dest := iface^.d_pixels;
+  dy := (iface^.s_height Shl 16) Div iface^.d_height;
+  dx := (iface^.s_width Shl 16) Div iface^.d_width;
+  y := 0;
+  Repeat
+    count := iface^.d_width;
+    x := 0;
+    Repeat
+      s_pixel := (Pint32(source)+(x Shr 16))^;
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+
+      Pint32(dest)^ := r Or g Or b;
+
+      Inc(x, dx);
+      Inc(dest, 4);
+      Dec(count);
+    Until count = 0;
+
+    Inc(dest, iface^.d_add);
+
+    Inc(y, dy);
+    Inc(source, (y Shr 16)*DWord(iface^.s_pitch));
+    y := y And $ffff;
+
+    Dec(iface^.d_height);
+  Until iface^.d_height = 0;
+End;
+
+Procedure ConvertP_Generic32_Generic24_S(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b : int32;
+  d_ptr : Pchar8;
+  count : DWord;
+  source, dest : Pchar8;
+  dx, dy, x, y : DWord;
+
+Begin
+  d_ptr := @s_pixel;
+  source := iface^.s_pixels;
+  dest := iface^.d_pixels;
+  dy := (iface^.s_height Shl 16) Div iface^.d_height;
+  dx := (iface^.s_width Shl 16) Div iface^.d_width;
+  y := 0;
+  Repeat
+    count := iface^.d_width;
+    x := 0;
+    Repeat
+      s_pixel := (Pint32(source)+(x Shr 16))^;
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+
+      s_pixel := r Or g Or b;
+
+      (dest + R_24)^ := (d_ptr + R_32)^;
+      (dest + G_24)^ := (d_ptr + G_32)^;
+      (dest + B_24)^ := (d_ptr + B_32)^;
+
+      Inc(x, dx);
+      Inc(dest, 3);
+      Dec(count);
+    Until count = 0;
+
+    Inc(dest, iface^.d_add);
+
+    Inc(y, dy);
+    Inc(source, (y Shr 16)*DWord(iface^.s_pitch));
+    y := y And $ffff;
+
+    Dec(iface^.d_height);
+  Until iface^.d_height = 0;
+End;
+
+Procedure ConvertP_Generic32_Generic16_S(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b : int32;
+  count : DWord;
+  source, dest : Pchar8;
+  dx, dy, x, y : DWord;
+
+Begin
+  source := iface^.s_pixels;
+  dest := iface^.d_pixels;
+  dy := (iface^.s_height Shl 16) Div iface^.d_height;
+  dx := (iface^.s_width Shl 16) Div iface^.d_width;
+  y := 0;
+  Repeat
+    count := iface^.d_width;
+    x := 0;
+    Repeat
+      s_pixel := (Pint32(source)+(x Shr 16))^;
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+
+      Pshort16(dest)^ := r Or g Or b;
+
+      Inc(x, dx);
+      Inc(dest, 2);
+      Dec(count);
+    Until count = 0;
+
+    Inc(dest, iface^.d_add);
+
+    Inc(y, dy);
+    Inc(source, (y Shr 16)*DWord(iface^.s_pitch));
+    y := y And $ffff;
+
+    Dec(iface^.d_height);
+  Until iface^.d_height = 0;
+End;
+
+Procedure ConvertP_Generic32_Generic8_S(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b : int32;
+  count : DWord;
+  source, dest : Pchar8;
+  dx, dy, x, y : DWord;
+
+Begin
+  source := iface^.s_pixels;
+  dest := iface^.d_pixels;
+  dy := (iface^.s_height Shl 16) Div iface^.d_height;
+  dx := (iface^.s_width Shl 16) Div iface^.d_width;
+  y := 0;
+  Repeat
+    count := iface^.d_width;
+    x := 0;
+    Repeat
+      s_pixel := (Pint32(source)+(x Shr 16))^;
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+
+      dest^ := r Or g Or b;
+
+      Inc(x, dx);
+      Inc(dest);
+      Dec(count);
+    Until count = 0;
+
+    Inc(dest, iface^.d_add);
+
+    Inc(y, dy);
+    Inc(source, (y Shr 16)*DWord(iface^.s_pitch));
+    y := y And $ffff;
+
+    Dec(iface^.d_height);
+  Until iface^.d_height = 0;
+End;
+
+Procedure ConvertP_Generic24_Generic32_S(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b : int32;
+  count : DWord;
+  source, src, dest : Pchar8;
+  dx, dy, x, y : DWord;
+
+Begin
+  source := iface^.s_pixels;
+  dest := iface^.d_pixels;
+  dy := (iface^.s_height Shl 16) Div iface^.d_height;
+  dx := (iface^.s_width Shl 16) Div iface^.d_width;
+  y := 0;
+  Repeat
+    count := iface^.d_width;
+    x := 0;
+    src := source;
+    Repeat
+      s_pixel := (((src+R_24)^) Shl 16) Or
+                 (((src+G_24)^) Shl 8) Or
+                 ((src+B_24)^);
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+
+      Pint32(dest)^ := r Or g Or b;
+
+      Inc(x, dx);
+      Inc(src, x Shr 16);
+      Inc(src, x Shr 16);
+      Inc(src, x Shr 16);
+      x := x And $FFFF;
+      Inc(dest, 4);
+      Dec(count);
+    Until count = 0;
+
+    Inc(dest, iface^.d_add);
+
+    Inc(y, dy);
+    Inc(source, (y Shr 16)*DWord(iface^.s_pitch));
+    y := y And $ffff;
+
+    Dec(iface^.d_height);
+  Until iface^.d_height = 0;
+End;
+
+Procedure ConvertP_Generic24_Generic24_S(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b : int32;
+  d_ptr : Pchar8;
+  count : DWord;
+  source, src, dest : Pchar8;
+  dx, dy, x, y : DWord;
+
+Begin
+  d_ptr := @s_pixel;
+  source := iface^.s_pixels;
+  dest := iface^.d_pixels;
+  dy := (iface^.s_height Shl 16) Div iface^.d_height;
+  dx := (iface^.s_width Shl 16) Div iface^.d_width;
+  y := 0;
+  Repeat
+    count := iface^.d_width;
+    x := 0;
+    src := source;
+    Repeat
+      s_pixel := (((src+R_24)^) Shl 16) Or
+                 (((src+G_24)^) Shl 8) Or
+                 ((src+B_24)^);
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+
+      s_pixel := r Or g Or b;
+
+      (dest + R_24)^ := (d_ptr + R_32)^;
+      (dest + G_24)^ := (d_ptr + G_32)^;
+      (dest + B_24)^ := (d_ptr + B_32)^;
+
+      Inc(x, dx);
+      Inc(src, x Shr 16);
+      Inc(src, x Shr 16);
+      Inc(src, x Shr 16);
+      x := x And $FFFF;
+      Inc(dest, 3);
+      Dec(count);
+    Until count = 0;
+
+    Inc(dest, iface^.d_add);
+
+    Inc(y, dy);
+    Inc(source, (y Shr 16)*DWord(iface^.s_pitch));
+    y := y And $ffff;
+
+    Dec(iface^.d_height);
+  Until iface^.d_height = 0;
+End;
+
+Procedure ConvertP_Generic24_Generic16_S(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b : int32;
+  count : DWord;
+  source, src, dest : Pchar8;
+  dx, dy, x, y : DWord;
+
+Begin
+  source := iface^.s_pixels;
+  dest := iface^.d_pixels;
+  dy := (iface^.s_height Shl 16) Div iface^.d_height;
+  dx := (iface^.s_width Shl 16) Div iface^.d_width;
+  y := 0;
+  Repeat
+    count := iface^.d_width;
+    x := 0;
+    src := source;
+    Repeat
+      s_pixel := (((src+R_24)^) Shl 16) Or
+                 (((src+G_24)^) Shl 8) Or
+                 ((src+B_24)^);
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+
+      Pshort16(dest)^ := r Or g Or b;
+
+      Inc(x, dx);
+      Inc(src, x Shr 16);
+      Inc(src, x Shr 16);
+      Inc(src, x Shr 16);
+      x := x And $FFFF;
+      Inc(dest, 2);
+      Dec(count);
+    Until count = 0;
+
+    Inc(dest, iface^.d_add);
+
+    Inc(y, dy);
+    Inc(source, (y Shr 16)*DWord(iface^.s_pitch));
+    y := y And $ffff;
+
+    Dec(iface^.d_height);
+  Until iface^.d_height = 0;
+End;
+
+Procedure ConvertP_Generic24_Generic8_S(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b : int32;
+  count : DWord;
+  source, src, dest : Pchar8;
+  dx, dy, x, y : DWord;
+
+Begin
+  source := iface^.s_pixels;
+  dest := iface^.d_pixels;
+  dy := (iface^.s_height Shl 16) Div iface^.d_height;
+  dx := (iface^.s_width Shl 16) Div iface^.d_width;
+  y := 0;
+  Repeat
+    count := iface^.d_width;
+    x := 0;
+    src := source;
+    Repeat
+      s_pixel := (((src+R_24)^) Shl 16) Or
+                 (((src+G_24)^) Shl 8) Or
+                 ((src+B_24)^);
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+
+      dest^ := r Or g Or b;
+
+      Inc(x, dx);
+      Inc(src, x Shr 16);
+      Inc(src, x Shr 16);
+      Inc(src, x Shr 16);
+      x := x And $FFFF;
+      Inc(dest);
+      Dec(count);
+    Until count = 0;
+
+    Inc(dest, iface^.d_add);
+
+    Inc(y, dy);
+    Inc(source, (y Shr 16)*DWord(iface^.s_pitch));
+    y := y And $ffff;
+
+    Dec(iface^.d_height);
+  Until iface^.d_height = 0;
+End;
+
+Procedure ConvertP_Generic16_Generic32_S(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b : int32;
+  count : DWord;
+  source, dest : Pchar8;
+  dx, dy, x, y : DWord;
+
+Begin
+  source := iface^.s_pixels;
+  dest := iface^.d_pixels;
+  dy := (iface^.s_height Shl 16) Div iface^.d_height;
+  dx := (iface^.s_width Shl 16) Div iface^.d_width;
+  y := 0;
+  Repeat
+    count := iface^.d_width;
+    x := 0;
+    Repeat
+      s_pixel := (Pshort16(source)+(x Shr 16))^;
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+
+      Pint32(dest)^ := r Or g Or b;
+
+      Inc(x, dx);
+      Inc(dest, 4);
+      Dec(count);
+    Until count = 0;
+
+    Inc(dest, iface^.d_add);
+
+    Inc(y, dy);
+    Inc(source, (y Shr 16)*DWord(iface^.s_pitch));
+    y := y And $ffff;
+
+    Dec(iface^.d_height);
+  Until iface^.d_height = 0;
+End;
+
+Procedure ConvertP_Generic16_Generic24_S(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b : int32;
+  d_ptr : Pchar8;
+  count : DWord;
+  source, dest : Pchar8;
+  dx, dy, x, y : DWord;
+
+Begin
+  d_ptr := @s_pixel;
+  source := iface^.s_pixels;
+  dest := iface^.d_pixels;
+  dy := (iface^.s_height Shl 16) Div iface^.d_height;
+  dx := (iface^.s_width Shl 16) Div iface^.d_width;
+  y := 0;
+  Repeat
+    count := iface^.d_width;
+    x := 0;
+    Repeat
+      s_pixel := (Pshort16(source)+(x Shr 16))^;
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+
+      s_pixel := r Or g Or b;
+
+      (dest + R_24)^ := (d_ptr + R_32)^;
+      (dest + G_24)^ := (d_ptr + G_32)^;
+      (dest + B_24)^ := (d_ptr + B_32)^;
+
+      Inc(x, dx);
+      Inc(dest, 3);
+      Dec(count);
+    Until count = 0;
+
+    Inc(dest, iface^.d_add);
+
+    Inc(y, dy);
+    Inc(source, (y Shr 16)*DWord(iface^.s_pitch));
+    y := y And $ffff;
+
+    Dec(iface^.d_height);
+  Until iface^.d_height = 0;
+End;
+
+Procedure ConvertP_Generic16_Generic16_S(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b : int32;
+  count : DWord;
+  source, dest : Pchar8;
+  dx, dy, x, y : DWord;
+
+Begin
+  source := iface^.s_pixels;
+  dest := iface^.d_pixels;
+  dy := (iface^.s_height Shl 16) Div iface^.d_height;
+  dx := (iface^.s_width Shl 16) Div iface^.d_width;
+  y := 0;
+  Repeat
+    count := iface^.d_width;
+    x := 0;
+    Repeat
+      s_pixel := (Pshort16(source)+(x Shr 16))^;
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+
+      Pshort16(dest)^ := r Or g Or b;
+
+      Inc(x, dx);
+      Inc(dest, 2);
+      Dec(count);
+    Until count = 0;
+
+    Inc(dest, iface^.d_add);
+
+    Inc(y, dy);
+    Inc(source, (y Shr 16)*DWord(iface^.s_pitch));
+    y := y And $ffff;
+
+    Dec(iface^.d_height);
+  Until iface^.d_height = 0;
+End;
+
+Procedure ConvertP_Generic16_Generic8_S(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b : int32;
+  count : DWord;
+  source, dest : Pchar8;
+  dx, dy, x, y : DWord;
+
+Begin
+  source := iface^.s_pixels;
+  dest := iface^.d_pixels;
+  dy := (iface^.s_height Shl 16) Div iface^.d_height;
+  dx := (iface^.s_width Shl 16) Div iface^.d_width;
+  y := 0;
+  Repeat
+    count := iface^.d_width;
+    x := 0;
+    Repeat
+      s_pixel := (Pshort16(source)+(x Shr 16))^;
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+
+      dest^ := r Or g Or b;
+
+      Inc(x, dx);
+      Inc(dest);
+      Dec(count);
+    Until count = 0;
+
+    Inc(dest, iface^.d_add);
+
+    Inc(y, dy);
+    Inc(source, (y Shr 16)*DWord(iface^.s_pitch));
+    y := y And $ffff;
+
+    Dec(iface^.d_height);
+  Until iface^.d_height = 0;
+End;
+
+Procedure ConvertP_Generic8_Generic32_S(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {todo}
+End;
+
+Procedure ConvertP_Generic8_Generic24_S(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {todo}
+End;
+
+Procedure ConvertP_Generic8_Generic16_S(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {todo}
+End;
+
+Procedure ConvertP_Generic8_Generic8_S(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {todo}
+End;

+ 617 - 0
packages/hermes/src/p_ga.inc

@@ -0,0 +1,617 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+{
+   Generic format conversion routines for the HERMES library
+   Copyright (c) 1998 Christian Nentwich ([email protected])
+   This source code is licensed under the GNU LGPL
+  
+   Please refer to the file COPYING.LIB contained in the distribution for
+   licensing conditions
+}
+
+Procedure ConvertP_Generic32_A_Generic32_A(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b, a : int32;
+  count : DWord;
+  source, dest : Pchar8;
+
+Begin
+  source := iface^.s_pixels; dest := iface^.d_pixels;
+  Repeat
+    count := iface^.s_width;
+    Repeat
+      s_pixel := Pint32(source)^;
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+      a := ((s_pixel Shr iface^.info.a_right) Shl iface^.info.a_left) And
+        iface^.mask_a;
+
+      Pint32(dest)^ := r Or g Or b Or a;
+
+      Inc(source, 4);
+      Inc(dest, 4);
+      Dec(count);
+    Until count = 0;
+
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+    Dec(iface^.s_height);
+  Until iface^.s_height = 0;
+End;
+
+Procedure ConvertP_Generic32_A_Generic24_A(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b, a : int32;
+  d_ptr : Pchar8;
+  count : DWord;
+  source, dest : Pchar8;
+
+Begin
+  d_ptr := @s_pixel;
+  source := iface^.s_pixels; dest := iface^.d_pixels;
+  Repeat
+    count := iface^.s_width;
+    Repeat
+      s_pixel := Pint32(source)^;
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+      a := ((s_pixel Shr iface^.info.a_right) Shl iface^.info.a_left) And
+        iface^.mask_a;
+
+      s_pixel := r Or g Or b Or a;
+
+      (dest+R_24)^ := (d_ptr+R_32)^;
+      (dest+G_24)^ := (d_ptr+G_32)^;
+      (dest+B_24)^ := (d_ptr+B_32)^;
+
+      Inc(source, 4);
+      Inc(dest, 3);
+      Dec(count);
+    Until count = 0;
+
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+    Dec(iface^.s_height);
+  Until iface^.s_height = 0;
+End;
+
+Procedure ConvertP_Generic32_A_Generic16_A(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b, a : int32;
+  count : DWord;
+  source, dest : Pchar8;
+
+Begin
+  source := iface^.s_pixels; dest := iface^.d_pixels;
+  Repeat
+    count := iface^.s_width Shr 1;
+
+    If count <> 0 Then
+      Repeat
+        r := (((Pint32(source)^) Shr iface^.info.r_right) Shl iface^.info.r_left) And
+	      iface^.mask_r;
+        g := (((Pint32(source)^) Shr iface^.info.g_right) Shl iface^.info.g_left) And
+	      iface^.mask_g;
+        b := (((Pint32(source)^) Shr iface^.info.b_right) Shl iface^.info.b_left) And
+	      iface^.mask_b;
+        a := (((Pint32(source)^) Shr iface^.info.a_right) Shl iface^.info.a_left) And
+	      iface^.mask_a;
+
+        s_pixel := (r Or g Or b Or a) And $FFFF;
+      
+        r := ((((Pint32(source)+1)^) Shr iface^.info.r_right) Shl iface^.info.r_left) And
+	      iface^.mask_r;
+        g := ((((Pint32(source)+1)^) Shr iface^.info.g_right) Shl iface^.info.g_left) And
+	      iface^.mask_g;
+        b := ((((Pint32(source)+1)^) Shr iface^.info.b_right) Shl iface^.info.b_left) And
+	      iface^.mask_b;
+        a := ((((Pint32(source)+1)^) Shr iface^.info.a_right) Shl iface^.info.a_left) And
+	      iface^.mask_a;
+
+        s_pixel := s_pixel Or ((r Or g Or b Or a) Shl 16);
+
+        Pint32(dest)^ := s_pixel;
+
+        Inc(source, 8);
+        Inc(dest, 4);
+        Dec(count);
+      Until count = 0;
+
+
+    { Trailing pixel }
+    
+    If (iface^.s_width And 1) <> 0 Then
+    Begin
+      r := (((Pint32(source)^) Shr iface^.info.r_right) Shl iface^.info.r_left) And
+	    iface^.mask_r;
+      g := (((Pint32(source)^) Shr iface^.info.g_right) Shl iface^.info.g_left) And
+	    iface^.mask_g;
+      b := (((Pint32(source)^) Shr iface^.info.b_right) Shl iface^.info.b_left) And
+	    iface^.mask_b;
+      a := (((Pint32(source)^) Shr iface^.info.a_right) Shl iface^.info.a_left) And
+	    iface^.mask_a;
+
+      Pshort16(dest)^ := r Or g Or b Or a;
+      Inc(dest, 2);
+      Inc(source, 4);
+    End;
+
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+    Dec(iface^.s_height);
+  Until iface^.s_height = 0;
+End;
+
+Procedure ConvertP_Generic32_A_Generic8_A(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b, a : int32;
+  count : DWord;
+  source, dest : Pchar8;
+
+Begin
+  source := iface^.s_pixels; dest := iface^.d_pixels;
+  Repeat
+    count := iface^.s_width;
+    Repeat
+      s_pixel := Pint32(source)^;
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+      a := ((s_pixel Shr iface^.info.a_right) Shl iface^.info.a_left) And
+        iface^.mask_a;
+
+      dest^ := r Or g Or b Or a;
+
+      Inc(source, 4);
+      Inc(dest);
+      Dec(count);
+    Until count = 0;
+
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+    Dec(iface^.s_height);
+  Until iface^.s_height = 0;
+End;
+
+Procedure ConvertP_Generic24_A_Generic32_A(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b, a : int32;
+  count : DWord;
+  source, dest : Pchar8;
+
+Begin
+  source := iface^.s_pixels; dest := iface^.d_pixels;
+  Repeat
+    count := iface^.s_width;
+    Repeat
+      s_pixel := ((Pint32(source+R_24)^) Shl 16) Or
+                 ((Pint32(source+G_24)^) Shl 8) Or
+                 (PInt32(source+B_24)^);
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+      a := ((s_pixel Shr iface^.info.a_right) Shl iface^.info.a_left) And
+        iface^.mask_a;
+
+      Pint32(dest)^ := r Or g Or b Or a;
+
+      Inc(source, 3);
+      Inc(dest, 4);
+      Dec(count);
+    Until count = 0;
+
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+    Dec(iface^.s_height);
+  Until iface^.s_height = 0;
+End;
+
+Procedure ConvertP_Generic24_A_Generic24_A(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b, a : int32;
+  d_ptr : Pchar8;
+  count : DWord;
+  source, dest : PChar8;
+
+Begin
+  d_ptr := @s_pixel;
+  source := iface^.s_pixels; dest := iface^.d_pixels;
+  Repeat
+    count := iface^.s_width;
+    Repeat
+      s_pixel := ((Pint32(source+R_24)^) Shl 16) Or
+                 ((Pint32(source+G_24)^) Shl 8) Or
+                 (PInt32(source+B_24)^);
+    
+      r := ((s_pixel Shl iface^.info.r_left) Shr iface^.info.r_right) And
+        iface^.mask_r;
+      g := ((s_pixel Shl iface^.info.g_left) Shr iface^.info.g_right) And
+        iface^.mask_g;
+      b := ((s_pixel Shl iface^.info.b_left) Shr iface^.info.b_right) And
+        iface^.mask_b;
+      a := ((s_pixel Shl iface^.info.a_left) Shr iface^.info.a_right) And
+        iface^.mask_a;
+
+      s_pixel := r Or g Or b Or a;
+
+      (dest + R_24)^ := (d_ptr + R_32)^;
+      (dest + G_24)^ := (d_ptr + G_32)^;
+      (dest + B_24)^ := (d_ptr + B_32)^;
+    
+      Inc(source, 3);
+      Inc(dest, 3);
+      Dec(count);
+    Until count = 0;
+
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+    Dec(iface^.s_height);
+  Until iface^.s_height = 0;
+End;
+
+Procedure ConvertP_Generic24_A_Generic16_A(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b, a : int32;
+  count : DWord;
+  source, dest : Pchar8;
+
+Begin
+  source := iface^.s_pixels; dest := iface^.d_pixels;
+  Repeat
+    count := iface^.s_width;
+    Repeat
+      s_pixel := ((Pint32(source+R_24)^) Shl 16) Or
+                 ((Pint32(source+G_24)^) Shl 8) Or
+                 (PInt32(source+B_24)^);
+    
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+      a := ((s_pixel Shr iface^.info.a_right) Shl iface^.info.a_left) And
+        iface^.mask_a;
+
+      Pshort16(dest)^ := r Or g Or b Or a;
+
+      Inc(source, 3);
+      Inc(dest, 2);
+      Dec(count);
+    Until count = 0;
+
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+    Dec(iface^.s_height);
+  Until iface^.s_height = 0;
+End;
+
+Procedure ConvertP_Generic24_A_Generic8_A(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b, a : int32;
+  count : DWord;
+  source, dest : Pchar8;
+
+Begin
+  source := iface^.s_pixels; dest := iface^.d_pixels;
+  Repeat
+    count := iface^.s_width;
+    Repeat
+      s_pixel := ((Pint32(source+R_24)^) Shl 16) Or
+                 ((Pint32(source+G_24)^) Shl 8) Or
+                 (PInt32(source+B_24)^);
+    
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+      a := ((s_pixel Shr iface^.info.a_right) Shl iface^.info.a_left) And
+        iface^.mask_a;
+    
+      dest^ := r Or g Or b Or a;
+    
+      Inc(source, 3);
+      Inc(dest);
+      Dec(count);
+    Until count = 0;
+
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+    Dec(iface^.s_height);
+  Until iface^.s_height = 0;
+End;
+
+Procedure ConvertP_Generic16_A_Generic32_A(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b, a : int32;
+  count : DWord;
+  source, dest : Pchar8;
+
+Begin
+  source := iface^.s_pixels; dest := iface^.d_pixels;
+  Repeat
+    count := iface^.s_width;
+    Repeat
+      s_pixel := Pshort16(source)^;
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+      a := ((s_pixel Shr iface^.info.a_right) Shl iface^.info.a_left) And
+        iface^.mask_a;
+
+      Pint32(dest)^ := r Or g Or b Or a;
+
+      Inc(source, 2);
+      Inc(dest, 4);
+      Dec(count);
+    Until count = 0;
+
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+    Dec(iface^.s_height);
+  Until iface^.s_height = 0;
+End;
+
+Procedure ConvertP_Generic16_A_Generic24_A(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b, a : int32;
+  d_ptr : Pchar8;
+  count : DWord;
+  source, dest : Pchar8;
+
+Begin
+  d_ptr := @s_pixel;
+  source := iface^.s_pixels; dest := iface^.d_pixels;
+  Repeat
+    count := iface^.s_width;
+    Repeat
+      s_pixel := Pshort16(source)^;
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+      a := ((s_pixel Shr iface^.info.a_right) Shl iface^.info.a_left) And
+        iface^.mask_a;
+    
+      s_pixel := r Or g Or b Or a;
+
+      (dest + R_24)^ := (d_ptr + R_32)^;
+      (dest + G_24)^ := (d_ptr + G_32)^;
+      (dest + B_24)^ := (d_ptr + B_32)^;
+    
+      Inc(source, 2);
+      Inc(dest, 3);
+      Dec(count);
+    Until count = 0;
+
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+    Dec(iface^.s_height);
+  Until iface^.s_height = 0;
+End;
+
+Procedure ConvertP_Generic16_A_Generic16_A(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b, a : int32;
+  count : DWord;
+  source, dest : Pchar8;
+
+Begin
+  source := iface^.s_pixels; dest := iface^.d_pixels;
+  Repeat
+    count := iface^.s_width;
+    Repeat
+      s_pixel := Pshort16(source)^;
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+      a := ((s_pixel Shr iface^.info.a_right) Shl iface^.info.a_left) And
+        iface^.mask_a;
+
+      Pshort16(dest)^ := r Or g Or b Or a;
+
+      Inc(source, 2);
+      Inc(dest, 2);
+      Dec(count);
+    Until count = 0;
+
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+    Dec(iface^.s_height);
+  Until iface^.s_height = 0;
+End;
+
+Procedure ConvertP_Generic16_A_Generic8_A(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b, a : int32;
+  count : DWord;
+  source, dest : Pchar8;
+
+Begin
+  source := iface^.s_pixels; dest := iface^.d_pixels;
+  Repeat
+    count := iface^.s_width;
+    Repeat
+      s_pixel := Pshort16(source)^;
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+      a := ((s_pixel Shr iface^.info.a_right) Shl iface^.info.a_left) And
+        iface^.mask_a;
+
+      dest^ := r Or g Or b Or a;
+
+      Inc(source, 2);
+      Inc(dest);
+      Dec(count);
+    Until count = 0;
+
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+    Dec(iface^.s_height);
+  Until iface^.s_height = 0;
+End;
+
+{ -------------------------------------------------------------------------
+
+                             STRETCH CONVERTERS
+   
+  ------------------------------------------------------------------------- }
+
+
+Procedure ConvertP_Generic32_A_Generic32_A_S(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b, a : int32;
+  count : DWord;
+  source, dest : Pchar8;
+  dx, dy, x, y : DWord;
+
+Begin
+  source := iface^.s_pixels;
+  dest := iface^.d_pixels;
+  dy := (iface^.s_height Shl 16) Div iface^.d_height;
+  dx := (iface^.s_width Shl 16) Div iface^.d_width;
+  y := 0;
+  Repeat
+    count := iface^.d_width;
+    x := 0;
+    Repeat
+      s_pixel := (Pint32(source)+(x Shr 16))^;
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+      a := ((s_pixel Shr iface^.info.a_right) Shl iface^.info.a_left) And
+        iface^.mask_a;
+    
+      Pint32(dest)^ := r Or g Or b Or a;
+    
+      Inc(x, dx);
+      Inc(dest, 4);
+      Dec(count);
+    Until count = 0;
+    
+    Inc(dest, iface^.d_add);
+    
+    Inc(y, dy);
+    Inc(source, (y Shr 16)*DWord(iface^.s_pitch));
+    y := y And $ffff;
+
+    Dec(iface^.d_height);
+  Until iface^.d_height = 0;
+End;
+
+Procedure ConvertP_Generic32_A_Generic16_A_S(iface : PHermesConverterInterface); CDecl;
+
+Var
+  s_pixel, r, g, b, a : int32;
+  count : DWord;
+  source, dest : Pchar8;
+  dx, dy, x, y : DWord;
+
+Begin
+  source := iface^.s_pixels;
+  dest := iface^.d_pixels;
+  dy := (iface^.s_height Shl 16) Div iface^.d_height;
+  dx := (iface^.s_width Shl 16) Div iface^.d_width;
+  y := 0;
+  Repeat
+    count := iface^.d_width;
+    x := 0;
+    Repeat
+      s_pixel := (Pint32(source)+(x Shr 16))^;
+
+      r := ((s_pixel Shr iface^.info.r_right) Shl iface^.info.r_left) And
+        iface^.mask_r;
+      g := ((s_pixel Shr iface^.info.g_right) Shl iface^.info.g_left) And
+        iface^.mask_g;
+      b := ((s_pixel Shr iface^.info.b_right) Shl iface^.info.b_left) And
+        iface^.mask_b;
+      a := ((s_pixel Shr iface^.info.a_right) Shl iface^.info.a_left) And
+        iface^.mask_a;
+    
+      Pshort16(dest)^ := r Or g Or b Or a;
+    
+      Inc(x, dx);
+      Inc(dest, 2);
+      Dec(count);
+    Until count = 0;
+    
+    Inc(dest, iface^.d_add);
+    
+    Inc(y, dy);
+    Inc(source, (y Shr 16)*DWord(iface^.s_pitch));
+    y := y And $ffff;
+
+    Dec(iface^.d_height);
+  Until iface^.d_height = 0;
+End;

+ 119 - 0
packages/hermes/src/p_gac.inc

@@ -0,0 +1,119 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+{
+   Generic format conversion routines for the HERMES library
+   Copyright (c) 1998 Christian Nentwich ([email protected])
+   This source code is licensed under the GNU LGPL
+  
+   Please refer to the file COPYING.LIB contained in the distribution for
+   licensing conditions
+}
+
+Procedure ConvertP_Generic32_A_Generic32_C(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic32_A_Generic24_C(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic32_A_Generic16_C(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic32_A_Generic8_C(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic24_A_Generic32_C(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic24_A_Generic24_C(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic24_A_Generic16_C(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic24_A_Generic8_C(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic16_A_Generic32_C(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic16_A_Generic24_C(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic16_A_Generic16_C(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic16_A_Generic8_C(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+{ -------------------------------------------------------------------------
+
+                             STRETCH CONVERTERS
+   
+  ------------------------------------------------------------------------- }
+
+
+Procedure ConvertP_Generic32_A_Generic32_C_S(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic32_A_Generic16_C_S(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;

+ 118 - 0
packages/hermes/src/p_gca.inc

@@ -0,0 +1,118 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+{
+   Generic format conversion routines for the HERMES library
+   Copyright (c) 1998 Christian Nentwich ([email protected])
+   This source code is licensed under the GNU LGPL
+  
+   Please refer to the file COPYING.LIB contained in the distribution for
+   licensing conditions
+}
+
+Procedure ConvertP_Generic32_C_Generic32_A(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic32_C_Generic24_A(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic32_C_Generic16_A(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic32_C_Generic8_A(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic24_C_Generic32_A(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic24_C_Generic24_A(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic24_C_Generic16_A(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic24_C_Generic8_A(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic16_C_Generic32_A(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic16_C_Generic24_A(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic16_C_Generic16_A(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic16_C_Generic8_A(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+{ -------------------------------------------------------------------------
+
+                             STRETCH CONVERTERS
+   
+  ------------------------------------------------------------------------- }
+
+Procedure ConvertP_Generic32_C_Generic32_A_S(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic32_C_Generic16_A_S(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;

+ 119 - 0
packages/hermes/src/p_gcc.inc

@@ -0,0 +1,119 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+{
+   Generic format conversion routines for the HERMES library
+   Copyright (c) 1998 Christian Nentwich ([email protected])
+   This source code is licensed under the GNU LGPL
+  
+   Please refer to the file COPYING.LIB contained in the distribution for
+   licensing conditions
+}
+
+Procedure ConvertP_Generic32_C_Generic32_C(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic32_C_Generic24_C(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic32_C_Generic16_C(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic32_C_Generic8_C(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic24_C_Generic32_C(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic24_C_Generic24_C(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic24_C_Generic16_C(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic24_C_Generic8_C(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic16_C_Generic32_C(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic16_C_Generic24_C(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic16_C_Generic16_C(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic16_C_Generic8_C(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+{ -------------------------------------------------------------------------
+
+                             STRETCH CONVERTERS
+   
+  ------------------------------------------------------------------------- }
+
+
+Procedure ConvertP_Generic32_C_Generic32_C_S(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;
+
+Procedure ConvertP_Generic32_C_Generic16_C_S(iface : PHermesConverterInterface); CDecl;
+
+Begin
+  {NOT YET IMPLEMENTED!}
+End;

+ 405 - 0
packages/hermes/src/p_i8.inc

@@ -0,0 +1,405 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+{
+
+   Generic C converter (from 8 bit indexed) for the HERMES library
+   Copyright (c) 1998 Christian Nentwich ([email protected])
+   This source code is licensed under the GNU LGPL
+
+   Please refer to the file COPYING.LIB contained in the distribution for
+   licensing conditions
+}
+
+{ -------------------------------------------------------------------------
+
+                             NORMAL CONVERTERS
+
+  ------------------------------------------------------------------------- }
+
+Procedure ConvertP_index8_32(iface : PHermesConverterInterface); CDecl;
+
+Var
+  i : Integer;
+  s_pixel : char8;
+  d_pixel : int32;
+  source, dest : Pchar8;
+
+Begin
+  source := iface^.s_pixels;
+  dest := iface^.d_pixels;
+  Repeat
+    For i := 0 To iface^.s_width - 1 Do
+    Begin
+      s_pixel := source^;
+      d_pixel := iface^.lookup[s_pixel];
+      Pint32(dest)^ := d_pixel;
+      Inc(source);
+      Inc(dest, 4);
+    End;
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+    Dec(iface^.s_height);
+  Until iface^.s_height = 0;
+End;
+
+Procedure ConvertP_index8_24(iface : PHermesConverterInterface); CDecl;
+
+Var
+  count : Integer;
+  s_pixel, s_pixel2, d_pixel : int32;
+  d_ptr, source, dest : Pchar8;
+
+Begin
+  d_ptr := @d_pixel;
+  source := iface^.s_pixels;
+  dest := iface^.d_pixels;
+  Repeat
+    count := iface^.d_width Shr 2;
+    While count <> 0 Do
+    Begin
+      Dec(count);
+
+      s_pixel := iface^.lookup[source^]; Inc(source);
+      s_pixel2 := iface^.lookup[source^]; Inc(source);
+
+      s_pixel := (s_pixel And $ffffff) Or (s_pixel2 Shl 24);
+      Pint32(dest)^ := s_pixel;
+
+      s_pixel := iface^.lookup[source^]; Inc(source);
+      s_pixel2 := ((s_pixel2 Shr 8) And $ffff) Or (s_pixel Shl 16);
+      Pint32(dest + 4)^ := s_pixel2;
+
+      s_pixel2 := iface^.lookup[source^]; Inc(source);
+      s_pixel := ((s_pixel Shr 16) And $ff) Or (s_pixel2 Shl 8);
+      Pint32(dest + 8)^ := s_pixel;
+
+      Inc(dest, 12);
+    End;
+
+    count := iface^.d_width And $3;
+    While count <> 0 Do
+    Begin
+      Dec(count);
+      d_pixel := iface^.lookup[source^]; Inc(source);
+
+      (dest + R_24)^ := (d_ptr + R_32)^;
+      (dest + G_24)^ := (d_ptr + G_32)^;
+      (dest + B_24)^ := (d_ptr + B_32)^;
+
+      Inc(dest, 3);
+    End;
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+    Dec(iface^.d_height);
+  Until iface^.d_height = 0;
+End;
+
+Procedure ConvertP_index8_16(iface : PHermesConverterInterface); CDecl;
+
+Var
+  source, dest : Pchar8;
+  count, c : DWord;
+
+Begin
+  source := iface^.s_pixels;
+  dest := iface^.d_pixels;
+  Repeat
+    count := iface^.s_width;
+    If (PtrUInt(dest) And $3) <> 0 Then
+    Begin
+      Pshort16(dest)^ := iface^.lookup[source^]; Inc(source);
+      Inc(dest, 2);
+      Dec(count);
+    End;
+    c := count Shr 1;
+    If c <> 0 Then
+      Repeat
+        Pint32(dest)^ := iface^.lookup[source^] Or
+                        (iface^.lookup[(source + 1)^] Shl 16);
+        Inc(dest, 4);
+        Inc(source, 2);
+        Dec(c);
+      Until c = 0;
+    If (count And 1) <> 0 Then
+    Begin
+      Pshort16(dest)^ := iface^.lookup[source^];
+      Inc(source);
+      Inc(dest, 2);
+    End;
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+    Dec(iface^.s_height);
+  Until iface^.s_height = 0;
+End;
+
+Procedure ConvertP_index8_8(iface : PHermesConverterInterface); CDecl;
+
+Var
+  source, dest : Pchar8;
+  count, c : DWord;
+
+Begin
+  source := iface^.s_pixels;
+  dest := iface^.d_pixels;
+  Repeat
+    count := iface^.s_width;
+    If (PtrUInt(dest) And $3) <> 0 Then
+    Begin
+      dest^ := iface^.lookup[source^]; Inc(source);
+      Inc(dest);
+      Dec(count);
+    End;
+    c := count Shr 2;
+    If c <> 0 Then
+      Repeat
+        Pint32(dest)^ := iface^.lookup[source^] Or
+                        (iface^.lookup[(source + 1)^] Shl 8) Or
+                        (iface^.lookup[(source + 2)^] Shl 16) Or
+                        (iface^.lookup[(source + 3)^] Shl 24);
+        Inc(dest, 4);
+        Inc(source, 4);
+        Dec(c);
+      Until c = 0;
+    count := count And $03;
+    While count > 0 Do
+    Begin
+      dest^ := iface^.lookup[source^]; Inc(source);
+      Inc(dest);
+      Dec(count);
+    End;
+    Inc(source, iface^.s_add);
+    Inc(dest, iface^.d_add);
+    Dec(iface^.s_height);
+  Until iface^.s_height = 0;
+End;
+
+{ -------------------------------------------------------------------------
+
+                             STRETCH CONVERTERS
+
+  ------------------------------------------------------------------------- }
+
+Procedure ConvertP_index8_32_S(iface : PHermesConverterInterface); CDecl;
+
+Var
+  x, y, count : DWord;
+  dx, dy : DWord;
+  source : Pchar8;
+
+Begin
+  y := 0;
+  dy := (iface^.s_height Shl 16) Div iface^.d_height;
+  dx := (iface^.s_width Shl 16) Div iface^.d_width;
+  source := iface^.s_pixels;
+  Repeat
+    count := iface^.d_width;
+    x := 0;
+
+    Repeat
+      Pint32(iface^.d_pixels)^ := iface^.lookup[(source + (x Shr 16))^];
+      Inc(x, dx);
+      Inc(iface^.d_pixels, 4);
+      Dec(count);
+    Until count = 0;
+
+    { Go to next destination row }
+    Inc(iface^.d_pixels, iface^.d_add);
+
+    { Calculate amount of rows to move in source surface }
+    Inc(y, dy);
+
+    Inc(source, (y Shr 16) * DWord(iface^.s_pitch));
+    y := y And $ffff;
+    Dec(iface^.d_height);
+  Until iface^.d_height = 0;
+End;
+
+{by me!}
+Procedure ConvertP_index8_24_S(iface : PHermesConverterInterface); CDecl;
+
+Var
+  x, y, count : DWord;
+  dx, dy : DWord;
+  source, dest : Pchar8;
+  s_pixel, s_pixel2, d_pixel : int32;
+
+Begin
+  y := 0;
+  dy := (iface^.s_height Shl 16) Div iface^.d_height;
+  dx := (iface^.s_width Shl 16) Div iface^.d_width;
+  source := iface^.s_pixels;
+  dest := iface^.d_pixels;
+  Repeat
+    x := 0;
+    count := iface^.d_width Shr 2;
+    While count <> 0 Do
+    Begin
+      Dec(count);
+
+      s_pixel := iface^.lookup[(source + (x Shr 16))^]; Inc(x, dx);
+      s_pixel2 := iface^.lookup[(source + (x Shr 16))^]; Inc(x, dx);
+
+      s_pixel := (s_pixel And $ffffff) Or (s_pixel2 Shl 24);
+      Pint32(dest)^ := s_pixel;
+
+      s_pixel := iface^.lookup[(source + (x Shr 16))^]; Inc(x, dx);
+      s_pixel2 := ((s_pixel2 Shr 8) And $ffff) Or (s_pixel Shl 16);
+      Pint32(dest + 4)^ := s_pixel2;
+
+      s_pixel2 := iface^.lookup[(source + (x Shr 16))^]; Inc(x, dx);
+      s_pixel := ((s_pixel Shr 16) And $ff) Or (s_pixel2 Shl 8);
+      Pint32(dest + 8)^ := s_pixel;
+
+      Inc(dest, 12);
+    End;
+
+    count := iface^.d_width And $3;
+    While count <> 0 Do
+    Begin
+      Dec(count);
+      d_pixel := iface^.lookup[(source + (x Shr 16))^]; Inc(x, dx);
+
+      Pshort16(dest)^ := d_pixel;
+      Pchar8(dest + 2)^ := d_pixel Shr 16;
+
+      Inc(dest, 3);
+    End;
+
+    { Go to next destination row }
+{    Inc(iface^.d_pixels, iface^.d_add);}
+    Inc(dest, iface^.d_add);
+
+    { Calculate amount of rows to move in source surface }
+    Inc(y, dy);
+
+    Inc(source, (y Shr 16) * DWord(iface^.s_pitch));
+    y := y And $ffff;
+    Dec(iface^.d_height);
+  Until iface^.d_height = 0;
+End;
+
+{ Quick hack of a index 8 to 16 stretch converter }
+Procedure ConvertP_index8_16_S(iface : PHermesConverterInterface); CDecl;
+
+Var
+  x, y, count : DWord;
+  dx, dy : DWord;
+  source, dest : Pchar8;
+
+Begin
+  y := 0;
+  dy := (iface^.s_height Shl 16) Div iface^.d_height;
+  dx := (iface^.s_width Shl 16) Div iface^.d_width;
+  source := iface^.s_pixels;
+  dest := iface^.d_pixels;
+  Repeat
+    { Do a two pixel at a time loop }
+
+    count := iface^.d_width Shr 1;
+    x := 0;
+
+    While count <> 0 Do
+    Begin
+      Dec(count);
+      Pint32(dest)^ := iface^.lookup[(source + (x Shr 16))^] Or
+                      (iface^.lookup[(source + ((x + dx) Shr 16))^] Shl 16);
+      Inc(x, dx); Inc(x, dx);
+      Inc(dest, 4);
+    End;
+
+    { Clean up remaining pixel if odd width }
+    If (iface^.d_width And 1) <> 0 Then
+    Begin
+      Pshort16(dest)^ := iface^.lookup[(source + (x Shr 16))^];
+      Inc(dest, 2);
+    End;
+
+    { Go to next destination row }
+    Inc(dest, iface^.d_add);
+
+    { Calculate amount of rows to move in source surface }
+    Inc(y, dy);
+
+    Inc(source, (y Shr 16) * DWord(iface^.s_pitch));
+    y := y And $ffff;
+    Dec(iface^.d_height);
+  Until iface^.d_height = 0;
+End;
+
+Procedure ConvertP_index8_8_S(iface : PHermesConverterInterface); CDecl;
+
+Var
+  x, y, count, c : DWord;
+  dx, dy : DWord;
+  source, dest : Pchar8;
+
+Begin
+  y := 0;
+  dy := (iface^.s_height Shl 16) Div iface^.d_height;
+  dx := (iface^.s_width Shl 16) Div iface^.d_width;
+  source := iface^.s_pixels;
+  dest := iface^.d_pixels;
+  Repeat
+    { Do a four pixel at a time loop }
+
+    count := iface^.d_width;
+    x := 0;
+
+    While ((PtrUInt(dest) And 3) <> 0) And (count > 0) Do
+    Begin
+      Dec(count);
+      dest^ := iface^.lookup[(source + (x Shr 16))^];
+      Inc(x, dx);
+      Inc(dest);
+    End;
+
+    c := count Shr 2;
+    count := count And 3;
+
+    While c <> 0 Do
+    Begin
+      Dec(c);
+      Pint32(dest)^ := iface^.lookup[(source + (x Shr 16))^] Or
+                      (iface^.lookup[(source + ((x + dx) Shr 16))^] Shl 8) Or
+                      (iface^.lookup[(source + ((x + (dx Shl 1)) Shr 16))^] Shl 16) Or
+                      (iface^.lookup[(source + ((x + dx + (dx Shl 1)) Shr 16))^] Shl 24);
+      Inc(x, dx Shl 2);
+      Inc(dest, 4);
+    End;
+
+    While count > 0 Do
+    Begin
+      Dec(count);
+      dest^ := iface^.lookup[(source + (x Shr 16))^];
+      Inc(dest);
+    End;
+
+    { Go to next destination row }
+    Inc(dest, iface^.d_add);
+
+    { Calculate amount of rows to move in source surface }
+    Inc(y, dy);
+
+    Inc(source, (y Shr 16) * DWord(iface^.s_pitch));
+    y := y And $ffff;
+    Dec(iface^.d_height);
+  Until iface^.d_height = 0;
+End;

+ 899 - 0
packages/hermes/src/p_muhmu.inc

@@ -0,0 +1,899 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+{
+   muhmuh converters for the HERMES library
+   Copyright (c) 1998 Christian Nentwich ([email protected])
+   This source code is licensed under the GNU LGPL
+ 
+   Please refer to the file COPYING.LIB contained in the distribution for
+   licensing conditions
+}
+
+{ TO 32 RGB }
+Procedure ConvertP_muhmu32_32rgb888(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  s_pixel : int32;
+
+Begin
+  Repeat
+    s_pixel := Pint32(source)^;
+
+    Pint32(dest)^ := (s_pixel And $ff) Or
+                    ((s_pixel And ($ff Shl 10)) Shr 2) Or
+	            ((s_pixel And ($ff Shl 20)) Shr 4);
+    
+    Inc(dest, 4);
+    Inc(source, 4);
+    Dec(count);
+  Until count = 0;
+End;
+
+{ TO 32 BGR }
+Procedure ConvertP_muhmu32_32bgr888(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  s_pixel : int32;
+
+Begin
+  Repeat
+    s_pixel := Pint32(source)^;
+
+    Pint32(dest)^ := ((s_pixel And $ff) Shl 16) Or
+                     ((s_pixel And ($ff Shl 10)) Shr 2) Or
+	             ((s_pixel Shr 20) And $FF);
+
+    Inc(dest, 4);
+    Inc(source, 4);
+    Dec(count);
+  Until count = 0;
+End;
+
+{ TO 32 RGBA }
+Procedure ConvertP_muhmu32_32rgba888(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  s_pixel : int32;
+
+Begin
+  Repeat
+    s_pixel := Pint32(source)^;
+
+    Pint32(dest)^ := (((s_pixel And $ff) Or
+                      ((s_pixel And ($ff Shl 10)) Shr 2) Or
+	              ((s_pixel And ($ff Shl 20)) Shr 4)) Shl 8) Or $FF;
+    
+    Inc(dest, 4);
+    Inc(source, 4);
+    Dec(count);
+  Until count = 0;
+End;
+
+{ TO 32 BGRA }
+Procedure ConvertP_muhmu32_32bgra888(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  s_pixel : int32;
+
+Begin
+  Repeat
+    s_pixel := Pint32(source)^;
+
+    Pint32(dest)^ := (((s_pixel And $ff) Shl 24) Or
+                      ((s_pixel And ($ff Shl 10)) Shl 6) Or
+	              ((s_pixel Shr 12) And $FF00)) Or $FF;
+
+    Inc(dest, 4);
+    Inc(source, 4);
+    Dec(count);
+  Until count = 0;
+End;
+
+{ TO 24 RGB }
+Procedure ConvertP_muhmu32_24rgb888(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  s_pixel : int32;
+  s_point : Pchar8;
+
+Begin
+  s_point := @s_pixel;
+  Repeat
+    s_pixel := Pint32(source)^;
+    s_pixel := (s_pixel And $ff) Or
+               ((s_pixel And ($ff Shl 10)) Shr 2) Or
+	       ((s_pixel And ($ff Shl 20)) Shr 4);
+
+    (dest+R_24)^ := (s_point+R_32)^;
+    (dest+G_24)^ := (s_point+G_32)^;
+    (dest+B_24)^ := (s_point+B_32)^;
+
+    Inc(source, 4);
+    Inc(dest, 3);
+    Dec(count);
+  Until count = 0;
+End;
+
+{ TO 24 BGR }
+Procedure ConvertP_muhmu32_24bgr888(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  s_pixel : int32;
+  s_point : Pchar8;
+
+Begin
+  s_point := @s_pixel;
+  Repeat
+    s_pixel := Pint32(source)^;
+    s_pixel := (s_pixel And $ff) Or
+               ((s_pixel And ($ff Shl 10)) Shr 2) Or
+	       ((s_pixel And ($ff Shl 20)) Shr 4);
+
+    { Note that R and B are swapped }
+    (dest+B_24)^ := (s_point+R_32)^;
+    (dest+G_24)^ := (s_point+G_32)^;
+    (dest+R_24)^ := (s_point+B_32)^;
+
+    Inc(source, 4);
+    Inc(dest, 3);
+    Dec(count);
+  Until count = 0;
+End;
+
+{ TO 16 RGB 565 }
+Procedure ConvertP_muhmu32_16rgb565(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  i : DWord;
+  r, g, b : int32;
+  s_pixel, d_pixelblock : int32;
+  d_pixel : short16;
+
+Begin
+  { If the current pixel isn't dword aligned, try write one pixel first }
+  If (PtrUInt(dest) And $3) <> 0 Then
+  Begin
+    s_pixel := Pint32(source)^;
+  
+    r := (s_pixel Shr 12) And $f800;
+    g := (s_pixel Shr 7) And $7e0;
+    b := (s_pixel Shr 3) And $1f;
+
+    d_pixel := r Or g Or b;
+
+    Pshort16(dest)^ := d_pixel;
+
+    Inc(source, 4);
+    Inc(dest, 2);
+    Dec(count);
+  End;
+
+  { Write blocks of two pixels }
+  For i := 1 To count Shr 1 Do
+  Begin
+    s_pixel := Pint32(source)^;
+
+    d_pixelblock := ((s_pixel Shr 12) And $f800) Or
+                    ((s_pixel Shr 7) And $7e0) Or
+		    ((s_pixel Shr 3) And $1f);
+
+    s_pixel := (Pint32(source) + 1)^;
+
+    d_pixelblock := d_pixelblock Or
+      ((((s_pixel Shr 12) And $f800) Or
+        ((s_pixel Shr 7) And $7e0) Or
+	((s_pixel Shr 3) And $1f)) Shl 16);
+
+    Pint32(dest)^ := d_pixelblock;
+    Inc(source, 8); Inc(dest, 4);
+  End;
+
+  { Eventually, write a single odd pixel that might be left }
+  If (count And 1) <> 0 Then
+  Begin
+    s_pixel := Pint32(source)^;
+
+    r := (s_pixel Shr 12) And $f800;
+    g := (s_pixel Shr 7) And $7e0;
+    b := (s_pixel Shr 3) And $1f;
+
+    d_pixel := r Or g Or b;
+
+    Pshort16(dest)^ := d_pixel;
+  End;
+End;
+
+{ TO 16 BGR 565 }
+Procedure ConvertP_muhmu32_16bgr565(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  i : DWord;
+  r, g, b : int32;
+  s_pixel, d_pixelblock : int32;
+  d_pixel : short16;
+
+Begin
+  { If the current pixel isn't dword aligned, try write one pixel first }
+  If (PtrUInt(dest) And $3) <> 0 Then
+  Begin
+    s_pixel := Pint32(source)^;
+  
+    r := (s_pixel Shr 23) And $1f;
+    g := (s_pixel Shr 7) And $7e0;
+    b := (s_pixel Shl 8) And $f800;
+
+    d_pixel := r Or g Or b;
+
+    Pshort16(dest)^ := d_pixel;
+
+    Inc(source, 4);
+    Inc(dest, 2);
+    Dec(count);
+  End;
+
+  { Write blocks of two pixels }
+  For i := 1 To count Shr 1 Do
+  Begin
+    s_pixel := Pint32(source)^;
+
+    d_pixelblock := ((s_pixel Shr 23) And $1f) Or
+                    ((s_pixel Shr 7) And $7e0) Or
+		    ((s_pixel Shl 8) And $f800);
+
+    s_pixel := (Pint32(source) + 1)^;
+
+    d_pixelblock := d_pixelblock Or
+      ((((s_pixel Shr 23) And $1f) Or
+        ((s_pixel Shr 7) And $7e0) Or
+	((s_pixel Shl 8) And $f800)) Shl 16);
+
+    Pint32(dest)^ := d_pixelblock;
+    Inc(source, 8); Inc(dest, 4);
+  End;
+
+  { Eventually, write a single odd pixel that might be left }
+  If (count And 1) <> 0 Then
+  Begin
+    s_pixel := Pint32(source)^;
+
+    r := (s_pixel Shr 23) And $1f;
+    g := (s_pixel Shr 7) And $7e0;
+    b := (s_pixel Shl 8) And $f800;
+
+    d_pixel := r Or g Or b;
+
+    Pshort16(dest)^ := d_pixel;
+  End;
+End;
+
+{ TO 16 RGB 555 }
+Procedure ConvertP_muhmu32_16rgb555(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  i : DWord;
+  r, g, b : int32;
+  s_pixel, d_pixelblock : int32;
+  d_pixel : short16;
+
+Begin
+  If (PtrUInt(dest) And $3) <> 0 Then
+  Begin
+    s_pixel := Pint32(source)^;
+  
+    r := (s_pixel Shr 13) And $7c00;
+    g := (s_pixel Shr 8) And $3e0;
+    b := (s_pixel Shr 3) And $1f;
+
+    d_pixel := r Or g Or b;
+
+    Pshort16(dest)^ := d_pixel;
+
+    Inc(source, 4);
+    Inc(dest, 2);
+    Dec(count);
+  End;
+
+  For i := 1 To count Shr 1 Do
+  Begin
+    s_pixel := Pint32(source)^;
+
+    d_pixelblock := ((s_pixel Shr 13) And $7c00) Or
+                    ((s_pixel Shr 8) And $3e0) Or
+		    ((s_pixel Shr 3) And $1f);
+
+    s_pixel := (Pint32(source) + 1)^;
+
+    d_pixelblock := d_pixelblock Or
+      ((((s_pixel Shr 13) And $7c00) Or
+        ((s_pixel Shr 8) And $3e0) Or
+	((s_pixel Shr 3) And $1f)) Shl 16);
+
+    Pint32(dest)^ := d_pixelblock;
+    Inc(source, 8); Inc(dest, 4);
+  End;
+
+  If (count And 1) <> 0 Then
+  Begin
+    s_pixel := Pint32(source)^;
+
+    r := (s_pixel Shr 13) And $7c00;
+    g := (s_pixel Shr 8) And $3e0;
+    b := (s_pixel Shr 3) And $1f;
+
+    d_pixel := r Or g Or b;
+
+    Pshort16(dest)^ := d_pixel;
+  End;
+End;
+
+{ TO 16 BGR 555 }
+Procedure ConvertP_muhmu32_16bgr555(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  i : DWord;
+  r, g, b : int32;
+  s_pixel, d_pixelblock : int32;
+  d_pixel : short16;
+
+Begin
+  If (PtrUInt(dest) And $3) <> 0 Then
+  Begin
+    s_pixel := Pint32(source)^;
+  
+    r := (s_pixel Shr 23) And $1f;
+    g := (s_pixel Shr 8) And $3e0;
+    b := (s_pixel Shl 7) And $7c00;
+
+    d_pixel := r Or g Or b;
+
+    Pshort16(dest)^ := d_pixel;
+
+    Inc(source, 4);
+    Inc(dest, 2);
+    Dec(count);
+  End;
+
+  For i := 1 To count Shr 1 Do
+  Begin
+    s_pixel := Pint32(source)^;
+
+    d_pixelblock := ((s_pixel Shr 23) And $1f) Or
+                    ((s_pixel Shr 8) And $3e0) Or
+		    ((s_pixel Shl 7) And $7c00);
+
+    s_pixel := (Pint32(source) + 1)^;
+
+    d_pixelblock := d_pixelblock Or
+      ((((s_pixel Shr 23) And $1f) Or
+        ((s_pixel Shr 8) And $3e0) Or
+	((s_pixel Shl 7) And $7c00)) Shl 16);
+
+    Pint32(dest)^ := d_pixelblock;
+    Inc(source, 8); Inc(dest, 4);
+  End;
+
+  If (count And 1) <> 0 Then
+  Begin
+    s_pixel := Pint32(source)^;
+
+    r := (s_pixel Shr 23) And $1f;
+    g := (s_pixel Shr 8) And $3e0;
+    b := (s_pixel Shl 7) And $7c00;
+
+    d_pixel := r Or g Or b;
+
+    Pshort16(dest)^ := d_pixel;
+  End;
+End;
+
+{ TO 8 RGB 332 }
+Procedure ConvertP_muhmu32_8rgb332(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  i : DWord;
+  s_pixel, d_block : int32;
+  d_pixel : char8;
+
+Begin
+  { Process single pixels until we are dword aligned }
+  While (PtrUInt(dest) And $3) <> 0 Do
+  Begin
+    s_pixel := Pint32(source)^;
+
+    d_pixel := ((s_pixel Shr 20) And $e0) Or
+               ((s_pixel Shr 13) And $1c) Or
+	       ((s_pixel Shr 6) And $3);
+
+    dest^ := d_pixel;
+
+    Dec(count);
+    If count = 0 Then
+      Exit;
+    Inc(dest);
+    Inc(source, 4);
+  End;
+
+  { Now process blocks of four pixels }
+  For i := 1 To count Shr 2 Do
+  Begin
+    s_pixel := Pint32(source)^;
+    d_block := ((s_pixel Shr 20) And $e0) Or
+               ((s_pixel Shr 13) And $1c) Or
+	       ((s_pixel Shr 6) And $3);
+
+    s_pixel := (Pint32(source) + 1)^;
+    d_block := d_block Or
+               ((((s_pixel Shr 20) And $e0) Or
+                 ((s_pixel Shr 13) And $1c) Or
+	         ((s_pixel Shr 6) And $3)) Shl 8);
+
+    s_pixel := (Pint32(source) + 2)^;
+    d_block := d_block Or
+               ((((s_pixel Shr 20) And $e0) Or
+                 ((s_pixel Shr 13) And $1c) Or
+	         ((s_pixel Shr 6) And $3)) Shl 16);
+
+    s_pixel := (Pint32(source) + 3)^;
+    d_block := d_block Or
+               ((((s_pixel Shr 20) And $e0) Or
+                 ((s_pixel Shr 13) And $1c) Or
+	         ((s_pixel Shr 6) And $3)) Shl 24);
+
+    Pint32(dest)^ := d_block;
+    Inc(source, 16);
+    Inc(dest, 4);
+  End;
+
+  { Write all possibly remaining pixel }
+  count := count And 3;
+  While count <> 0 Do
+  Begin
+    Dec(count);
+    dest^ := ((s_pixel Shr 20) And $e0) Or
+             ((s_pixel Shr 13) And $1c) Or
+	     ((s_pixel Shr 6) And $3);
+
+    Inc(dest);
+    Inc(source, 4);
+  End;
+End;
+
+{ -------------------------------------------------------------------------
+
+                             STRETCH CONVERTERS
+   
+  ------------------------------------------------------------------------- }
+
+Procedure ConvertP_muhmu32_32rgb888_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x : DWord;
+  s_pixel : DWord;
+
+Begin
+  x := 0;
+  While count > 0 Do
+  Begin
+    s_pixel := Pint32(source)^;
+    Pint32(dest)^ := (s_pixel And $ff) Or
+                    ((s_pixel And ($ff Shl 10)) Shr 2) Or
+	            ((s_pixel And ($ff Shl 20)) Shr 4);
+    Inc(x, inc_source);
+    Inc(source, (x Shr 16)*4);
+    x := x And $FFFF;
+    Inc(dest, 4);
+    Dec(count);
+  End;
+End;
+
+Procedure ConvertP_muhmu32_32bgr888_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x : DWord;
+  s_pixel : DWord;
+
+Begin
+  x := 0;
+  While count > 0 Do
+  Begin
+    s_pixel := Pint32(source)^;
+    Pint32(dest)^ := ((s_pixel And $ff) Shl 16) Or
+                     ((s_pixel And ($ff Shl 10)) Shr 2) Or
+	             ((s_pixel Shr 20) And $FF);
+    Inc(x, inc_source);
+    Inc(source, (x Shr 16)*4);
+    x := x And $FFFF;
+    Inc(dest, 4);
+    Dec(count);
+  End;
+End;
+
+Procedure ConvertP_muhmu32_32rgba888_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x : DWord;
+  s_pixel : DWord;
+
+Begin
+  x := 0;
+  While count > 0 Do
+  Begin
+    s_pixel := Pint32(source)^;
+    Pint32(dest)^ := (((s_pixel And $ff) Or
+                      ((s_pixel And ($ff Shl 10)) Shr 2) Or
+	              ((s_pixel And ($ff Shl 20)) Shr 4)) Shl 8) Or $FF;
+    Inc(x, inc_source);
+    Inc(source, (x Shr 16)*4);
+    x := x And $FFFF;
+    Inc(dest, 4);
+    Dec(count);
+  End;
+End;
+
+Procedure ConvertP_muhmu32_32bgra888_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x : DWord;
+  s_pixel : DWord;
+
+Begin
+  x := 0;
+  While count > 0 Do
+  Begin
+    s_pixel := Pint32(source)^;
+    Pint32(dest)^ := (((s_pixel And $ff) Shl 24) Or
+                      ((s_pixel And ($ff Shl 10)) Shl 6) Or
+	              ((s_pixel Shr 12) And $FF00)) Or $FF;
+    Inc(x, inc_source);
+    Inc(source, (x Shr 16)*4);
+    x := x And $FFFF;
+    Inc(dest, 4);
+    Dec(count);
+  End;
+End;
+
+Procedure ConvertP_muhmu32_24rgb888_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x : DWord;
+  p1, p2, p3, p4 : DWord;
+  c : DWord;
+
+Begin
+  x := 0;
+  While (PtrUInt(dest) And 3) <> 0 Do
+  Begin
+    p1 := (Pint32(source) + (x Shr 16))^;
+    p1 := (p1 And $ff) Or
+         ((p1 And ($ff Shl 10)) Shr 2) Or
+         ((p1 And ($ff Shl 20)) Shr 4);
+    Pshort16(dest)^ := p1 And $FFFF;
+    Pchar8(dest + 2)^ := p1 Shr 16;
+    
+    Inc(x, inc_source);
+    Inc(dest, 3);
+    Dec(count);
+    If count = 0 Then
+      Exit;
+  End;
+  
+  c := count Shr 2;
+  While c > 0 Do
+  Begin
+    p1 := (Pint32(source) + (x Shr 16))^;
+    p2 := (Pint32(source) + ((x + inc_source) Shr 16))^;
+    p3 := (Pint32(source) + ((x + 2*inc_source) Shr 16))^;
+    p4 := (Pint32(source) + ((x + 3*inc_source) Shr 16))^;
+    
+    Pint32(dest + 0)^ := ((p2 And $FF) Shl 24) Or ((p1 And $FF00000) Shr 4) Or ((p1 And $3FC00) Shr 2) Or (p1 And $FF);
+    Pint32(dest + 4)^ := ((p3 And $3FC00) Shl 14) Or ((p3 And $FF) Shl 16) Or ((p2 And $FF00000) Shr 12) Or ((p2 And $3FC00) Shr 10);
+    Pint32(dest + 8)^ := ((p4 And $FF00000) Shl 4) Or ((p4 And $3FC00) Shl 6) Or ((p4 And $FF) Shl 8) Or ((p3 And $FF00000) Shr 20);
+    
+    Dec(c);
+    Inc(x, inc_source*4);
+    Inc(dest, 12);
+  End;
+  
+  count := count And 3;
+  While count > 0 Do
+  Begin
+    p1 := (Pint32(source) + (x Shr 16))^;
+    p1 := (p1 And $ff) Or
+         ((p1 And ($ff Shl 10)) Shr 2) Or
+         ((p1 And ($ff Shl 20)) Shr 4);
+    Pshort16(dest)^ := p1 And $FFFF;
+    Pchar8(dest + 2)^ := p1 Shr 16;
+    
+    Inc(x, inc_source);
+    Inc(dest, 3);
+    Dec(count);
+  End;
+End;
+
+Procedure ConvertP_muhmu32_24bgr888_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x : DWord;
+  p1, p2, p3, p4 : DWord;
+  c : DWord;
+
+Begin
+  x := 0;
+  While (PtrUInt(dest) And 3) <> 0 Do
+  Begin
+    p1 := (Pint32(source) + (x Shr 16))^;
+    p1 := ((p1 And $ff) Shl 16) Or
+          ((p1 And ($ff Shl 10)) Shr 2) Or
+          ((p1 And ($ff Shl 20)) Shr 20);
+    Pshort16(dest)^ := p1 And $FFFF;
+    Pchar8(dest + 2)^ := p1 Shr 16;
+    
+    Inc(x, inc_source);
+    Inc(dest, 3);
+    Dec(count);
+    If count = 0 Then
+      Exit;
+  End;
+  
+  c := count Shr 2;
+  While c > 0 Do
+  Begin
+    p1 := (Pint32(source) + (x Shr 16))^;
+    p2 := (Pint32(source) + ((x + inc_source) Shr 16))^;
+    p3 := (Pint32(source) + ((x + 2*inc_source) Shr 16))^;
+    p4 := (Pint32(source) + ((x + 3*inc_source) Shr 16))^;
+    
+    Pint32(dest + 0)^ := ((p2 And $FF00000) Shl 4) Or ((p1 And $FF) Shl 16) Or ((p1 And $3FC00) Shr 2) Or ((p1 And $FF00000) Shr 20);
+    Pint32(dest + 4)^ := ((p3 And $3FC00) Shl 14) Or ((p3 And $FF00000) Shr 4) Or ((p2 And $FF) Shl 8) Or ((p2 And $3FC00) Shr 10);
+    Pint32(dest + 8)^ := ((p4 And $FF) Shl 24) Or ((p4 And $3FC00) Shl 6) Or ((p4 And $FF00000) Shr 12) Or (p3 And $FF);
+    
+    Dec(c);
+    Inc(x, inc_source*4);
+    Inc(dest, 12);
+  End;
+  
+  count := count And 3;
+  While count > 0 Do
+  Begin
+    p1 := (Pint32(source) + (x Shr 16))^;
+    p1 := ((p1 And $ff) Shl 16) Or
+          ((p1 And ($ff Shl 10)) Shr 2) Or
+          ((p1 And ($ff Shl 20)) Shr 20);
+    Pshort16(dest)^ := p1 And $FFFF;
+    Pchar8(dest + 2)^ := p1 Shr 16;
+    
+    Inc(x, inc_source);
+    Inc(dest, 3);
+    Dec(count);
+  End;
+End;
+
+Procedure ConvertP_muhmu32_16rgb565_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x, c : DWord;
+  p : int32;
+
+Begin
+  x := 0;
+  { Try to write 2 pixel blocks }
+  c := count Shr 1; 
+  While c <> 0 Do
+  Begin
+    Dec(c);
+    p := (((Pint32(source) + (x Shr 16))^ Shr 12) And $f800) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 7) And $7e0) Or
+	 (((Pint32(source) + (x Shr 16))^ Shr 3) And $1f);
+    Inc(x, inc_source);
+
+    p := p Or
+       (((((Pint32(source) + (x Shr 16))^ Shr 12) And $f800) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 7) And $7e0) Or
+	 (((Pint32(source) + (x Shr 16))^ Shr 3) And $1f)) Shl 16);
+    Inc(x, inc_source);
+
+    Pint32(dest)^ := p;
+
+    Inc(dest, 4);
+  End;
+
+  { Write trailing pixel }
+  If (count And 1) <> 0 Then
+    Pshort16(dest)^ := (((Pint32(source) + (x Shr 16))^ Shr 12) And $f800) Or
+                       (((Pint32(source) + (x Shr 16))^ Shr 7) And $7e0) Or
+	               (((Pint32(source) + (x Shr 16))^ Shr 3) And $1f);
+End;
+
+Procedure ConvertP_muhmu32_16bgr565_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x, c : DWord;
+  p : int32;
+
+Begin
+  x := 0;
+  { Try to write 2 pixel blocks }
+  c := count Shr 1; 
+  While c <> 0 Do
+  Begin
+    Dec(c);
+    p := (((Pint32(source) + (x Shr 16))^ Shr 23) And $1f) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 7) And $7e0) Or
+	 (((Pint32(source) + (x Shr 16))^ Shl 8) And $f800);
+    Inc(x, inc_source);
+
+    p := p Or
+       (((((Pint32(source) + (x Shr 16))^ Shr 23) And $1f) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 7) And $7e0) Or
+	 (((Pint32(source) + (x Shr 16))^ Shl 8) And $f800)) Shl 16);
+    Inc(x, inc_source);
+
+    Pint32(dest)^ := p;
+
+    Inc(dest, 4);
+  End;
+
+  { Write trailing pixel }
+  If (count And 1) <> 0 Then
+    Pshort16(dest)^ := (((Pint32(source) + (x Shr 16))^ Shr 23) And $1f) Or
+                       (((Pint32(source) + (x Shr 16))^ Shr 7) And $7e0) Or
+	               (((Pint32(source) + (x Shr 16))^ Shl 8) And $f800);
+End;
+
+Procedure ConvertP_muhmu32_16rgb555_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x, c : DWord;
+  p : int32;
+
+Begin
+  x := 0;
+  { Try to write 2 pixel blocks }
+  c := count Shr 1; 
+  While c <> 0 Do
+  Begin
+    Dec(c);
+    p := (((Pint32(source) + (x Shr 16))^ Shr 13) And $7c00) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 8) And $3e0) Or
+	 (((Pint32(source) + (x Shr 16))^ Shr 3) And $1f);
+    Inc(x, inc_source);
+
+    p := p Or
+       (((((Pint32(source) + (x Shr 16))^ Shr 13) And $7c00) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 8) And $3e0) Or
+	 (((Pint32(source) + (x Shr 16))^ Shr 3) And $1f)) Shl 16);
+    Inc(x, inc_source);
+
+    Pint32(dest)^ := p;
+
+    Inc(dest, 4);
+  End;
+
+  { Write trailing pixel }
+  If (count And 1) <> 0 Then
+    Pshort16(dest)^ := (((Pint32(source) + (x Shr 16))^ Shr 13) And $7c00) Or
+                       (((Pint32(source) + (x Shr 16))^ Shr 8) And $3e0) Or
+	               (((Pint32(source) + (x Shr 16))^ Shr 3) And $1f);
+End;
+
+Procedure ConvertP_muhmu32_16bgr555_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x, c : DWord;
+  p : int32;
+
+Begin
+  x := 0;
+  { Try to write 2 pixel blocks }
+  c := count Shr 1; 
+  While c <> 0 Do
+  Begin
+    Dec(c);
+    p := (((Pint32(source) + (x Shr 16))^ Shr 23) And $1f) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 8) And $3e0) Or
+	 (((Pint32(source) + (x Shr 16))^ Shl 7) And $7c00);
+    Inc(x, inc_source);
+
+    p := p Or
+       (((((Pint32(source) + (x Shr 16))^ Shr 23) And $1f) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 8) And $3e0) Or
+	 (((Pint32(source) + (x Shr 16))^ Shl 7) And $7c00)) Shl 16);
+    Inc(x, inc_source);
+
+    Pint32(dest)^ := p;
+
+    Inc(dest, 4);
+  End;
+
+  { Write trailing pixel }
+  If (count And 1) <> 0 Then
+    Pshort16(dest)^ := (((Pint32(source) + (x Shr 16))^ Shr 23) And $1f) Or
+                       (((Pint32(source) + (x Shr 16))^ Shr 8) And $3e0) Or
+	               (((Pint32(source) + (x Shr 16))^ Shl 7) And $7c00);
+End;
+
+Procedure ConvertP_muhmu32_8rgb332_S(source, dest : Pchar8; count, inc_source : DWord); CDecl;
+
+Var
+  x, c : DWord;
+  p : int32;
+
+Begin
+  x := 0;
+
+  { Write single pixels until the destination address is aligned mod 4 }
+  While (PtrUInt(dest) And $3) <> 0 Do
+  Begin
+    dest^ := (((Pint32(source) + (x Shr 16))^ Shr 20) And $e0) Or
+             (((Pint32(source) + (x Shr 16))^ Shr 13) And $1c) Or
+	     (((Pint32(source) + (x Shr 16))^ Shr 6) And $3);
+    Inc(x, inc_source);
+    Inc(dest);
+    Dec(count);
+    If count = 0 Then
+      Exit;
+  End;
+
+  { Write blocks of four pixels now }
+  c := count Shr 2;
+  While c <> 0 Do
+  Begin
+    Dec(c);
+    p := (((Pint32(source) + (x Shr 16))^ Shr 20) And $e0) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 13) And $1c) Or
+	 (((Pint32(source) + (x Shr 16))^ Shr 6) And $3);
+    Inc(x, inc_source);
+
+    p := p Or
+       (((((Pint32(source) + (x Shr 16))^ Shr 20) And $e0) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 13) And $1c) Or
+	 (((Pint32(source) + (x Shr 16))^ Shr 6) And $3)) Shl 8);
+    Inc(x, inc_source);
+
+    p := p Or
+       (((((Pint32(source) + (x Shr 16))^ Shr 20) And $e0) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 13) And $1c) Or
+	 (((Pint32(source) + (x Shr 16))^ Shr 6) And $3)) Shl 16);
+    Inc(x, inc_source);
+
+    p := p Or
+       (((((Pint32(source) + (x Shr 16))^ Shr 20) And $e0) Or
+         (((Pint32(source) + (x Shr 16))^ Shr 13) And $1c) Or
+	 (((Pint32(source) + (x Shr 16))^ Shr 6) And $3)) Shl 24);
+    Inc(x, inc_source);
+
+    Pint32(dest)^ := p;
+
+    Inc(dest, 4);
+  End;
+
+  { Write up to three trailing pixels }
+  c := count And $3;
+  While c <> 0 Do
+  Begin
+    Dec(c);
+    dest^ := (((Pint32(source) + (x Shr 16))^ Shr 20) And $e0) Or
+             (((Pint32(source) + (x Shr 16))^ Shr 13) And $1c) Or
+	     (((Pint32(source) + (x Shr 16))^ Shr 6) And $3);
+    Inc(x, inc_source);
+    Inc(dest);
+  End;
+End;

+ 348 - 0
packages/hermes/src/palette.inc

@@ -0,0 +1,348 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+Type
+  PHermesLookupTable = ^THermesLookupTable;
+  THermesLookupTable = Record
+    data : ^int32;             { Actual lookup table }
+    valid : Boolean;           { Is this table up to date? }
+    format : THermesFormat;    { Format of lookup table }
+  End;
+  PHermesPalette = ^THermesPalette;
+  THermesPalette = Record
+    data : ^int32;             { Palette data }
+    tables : PHermesList;      { Linked list of HermesLookupTables }
+  End;
+
+Const
+  PaletteList : PHermesList = Nil;
+  PALETTErefcount : Integer = 0;
+  currenthandle : THermesHandle = 0;
+
+{Function Hermes_PaletteGetTable(palette : THermesHandle; format : PHermesFormat) : Pointer;
+Procedure Hermes_PaletteMakeLookup(lookup, palette : Pint32;
+                                   format : PHermesFormat);
+
+Function Hermes_PaletteInstance : THermesHandle;
+Procedure Hermes_PaletteReturn(handle : THermesHandle);
+Procedure Hermes_PaletteSet(handle : THermesHandle; palette : Pointer);
+Function Hermes_PaletteGet(handle : THermesHandle) : Pointer;
+Procedure Hermes_PaletteInvalidateCache(handle : THermesHandle);}
+
+Function Hermes_PaletteInstance : THermesHandle;
+
+Var
+  newinstance : PHermesPalette;
+  newelement : PHermesListElement;
+
+Begin
+  If PaletteList = Nil Then
+  Begin
+    PaletteList := Hermes_ListNew;
+    { Could not create a new list }
+    If PaletteList = Nil Then
+    Begin
+      Hermes_PaletteInstance := 0;
+      Exit;
+    End;
+  End;
+  { Create a new palette structure }
+  newinstance := malloc(SizeOf(THermesPalette));
+  If newinstance = Nil Then
+  Begin
+    Hermes_PaletteInstance := 0;
+    Exit;
+  End;
+  { Create palette data }
+  newinstance^.data := malloc(256*SizeOf(int32));
+  If newinstance^.data = Nil Then
+  Begin
+    free(newinstance);
+    Hermes_PaletteInstance := 0;
+    Exit;
+  End;
+  { Create lookup table list }
+  newinstance^.tables := Hermes_ListNew;
+  If newinstance^.tables = Nil Then
+  Begin
+    free(newinstance^.data);
+    free(newinstance);
+    Hermes_PaletteInstance := 0;
+    Exit;
+  End;
+  { Everything fine so far, create a new list element }
+  newelement := Hermes_ListElementNew(currenthandle+1);
+  If newelement = Nil Then
+  Begin
+    Hermes_ListDestroy(newinstance^.tables);
+    free(newinstance^.data);
+    free(newinstance);
+    Hermes_PaletteInstance := 0;
+    Exit;
+  End;
+
+  { No errors, put current palette structure into the list element and add
+    that to the list }
+  newelement^.data := newinstance;
+
+  Hermes_ListAdd(PaletteList, newelement);
+
+  Inc(PALETTErefcount);
+  Inc(currenthandle);
+  Hermes_PaletteInstance := currenthandle;
+End;
+
+Procedure Hermes_PaletteReturn(handle : THermesHandle);
+
+Var
+  element : PHermesListElement;
+  pal : PHermesPalette;
+  table : PHermesLookupTable;
+
+Begin
+  element := Hermes_ListLookup(PaletteList, handle);
+  If element = Nil Then
+    Exit;
+
+  pal := element^.data;
+
+
+  { Free palette data and lookup tables }
+  free(pal^.data);
+
+  element := pal^.tables^.first;
+  While element <> Nil Do
+  Begin
+    table := element^.data;
+    If (table <> Nil) And (table^.data <> Nil) Then
+    Begin
+      free(table^.data);
+      table^.data := Nil;
+    End;
+    element := element^.next;
+  End;
+  Hermes_ListDestroy(pal^.tables);
+
+
+  { Delete list element that holds this palette }
+  Hermes_ListDeleteElement(PaletteList, handle);
+
+
+  { Decrease reference count. If down to zero, delete palette list }
+  Dec(PALETTErefcount);
+  If PALETTErefcount = 0 Then
+  Begin
+    Hermes_ListDestroy(PaletteList);
+    PaletteList := Nil;
+  End;
+End;
+
+Procedure Hermes_PaletteSet(handle : THermesHandle; palette : Pointer);
+
+Var
+  element : PHermesListElement;
+  pal : PHermesPalette;
+
+Begin
+{  DebugMSG('Hermes_PaletteSet('+C2Str(handle)+','+C2Str(DWord(palette))+')');}
+  element := Hermes_ListLookup(PaletteList, handle);
+  If element = Nil Then
+    Exit;
+
+  pal := element^.data;
+  element := pal^.tables^.first;
+
+  { Invalidate all lookup tables }
+
+  While element <> Nil Do
+  Begin
+    (PHermesLookupTable(element^.data))^.valid := False;
+    element := element^.next;
+  End;
+
+{  FillChar(palette^, 256*4, $7f);}
+  Move(palette^, pal^.data^, 256*4);
+End;
+
+Function Hermes_PaletteGet(handle : THermesHandle) : Pointer;
+
+Var
+  element : PHermesListElement;
+  pal : PHermesPalette;
+
+Begin
+  element := Hermes_ListLookup(PaletteList, handle);
+  If element = Nil Then
+  Begin
+    Hermes_PaletteGet := Nil;
+    Exit;
+  End;
+
+  pal := element^.data;
+  Hermes_PaletteGet := pal^.data;
+End;
+
+Procedure Hermes_PaletteMakeLookup(lookup, palette : Pint32;
+                                   format : PHermesFormat);
+
+Var
+  info : THermesGenericInfo;
+  I : Integer;
+  r, g, b : int32;
+
+Begin
+{  DebugMSG('Yo! Hermes_PaletteMakeLookup');}
+  r := 0;
+  g := 0;
+  b := 0;
+  If format^.indexed Then
+    Exit;
+
+  Hermes_Calculate_Generic_Info(24,16,8,32,
+                                Hermes_Topbit(format^.r),
+                                Hermes_Topbit(format^.g),
+                                Hermes_Topbit(format^.b),
+                                Hermes_Topbit(format^.a),
+                                @info);
+
+  { Optimised loop if there are no left shifts }
+  If (info.r_left = 0) And (info.g_left = 0) And (info.b_left = 0) Then
+    For I := 0 To 255 Do
+    Begin
+      r := (palette[i] Shr info.r_right) And format^.r;
+      g := (palette[i] Shr info.g_right) And format^.g;
+      b := (palette[i] Shr info.b_right) And format^.b;
+      lookup[i] := r Or g Or b;
+    End
+  Else
+    For I := 0 To 255 Do
+    Begin
+      r := ((palette[i] Shr info.r_right) Shl info.r_left) And format^.r;
+      g := ((palette[i] Shr info.g_right) Shl info.g_left) And format^.g;
+      b := ((palette[i] Shr info.b_right) Shl info.b_left) And format^.b;
+      lookup[i] := r Or g Or b;
+    End;
+End;
+
+Function Hermes_PaletteGetTable(palette : THermesHandle; format : PHermesFormat) : Pointer;
+
+Var
+  element : PHermesListElement;
+  pal : PHermesPalette;
+  table : PHermesLookupTable;
+
+Begin
+  element := Hermes_ListLookup(PaletteList, palette);
+  If element = Nil Then
+  Begin
+    Hermes_PaletteGetTable := Nil;
+    Exit;
+  End;
+
+  pal := element^.data;
+
+  { Go to the first table in the list }
+  element := pal^.tables^.first;
+
+  { Search for correct table using format }
+  While element <> Nil Do
+  Begin
+    table := element^.data;
+
+    If Hermes_FormatEquals(@table^.format, format) Then
+    Begin
+      If table^.valid Then
+      Begin
+        Hermes_PaletteGetTable := table^.data;
+        Exit;
+      End;
+
+      { Have to recreate the lookup table }
+      Hermes_PaletteMakeLookup(table^.data, pal^.data, format);
+      table^.valid := True;
+
+      Hermes_PaletteGetTable := table^.data;
+      Exit;
+    End;
+
+    element := element^.next;
+  End;
+
+  { Format not found, have to create a new table (need no handle) }
+  table := malloc(SizeOf(THermesLookupTable));
+  If table = Nil Then
+  Begin
+    Hermes_PaletteGetTable := Nil;
+    Exit;
+  End;
+
+  table^.data := malloc(1024);
+  If table^.data = Nil Then
+  Begin
+    Hermes_PaletteGetTable := Nil;
+    Exit;
+  End;
+
+  { Create lookup table }
+  Hermes_PaletteMakeLookup(table^.data, pal^.data, format);
+  Hermes_FormatCopy(format, @table^.format);
+
+  table^.valid := True;
+
+  { Create a new list element }
+  element := Hermes_ListElementNew(0);
+  If element = Nil Then
+  Begin
+    Hermes_PaletteGetTable := Nil;
+    Exit;
+  End;
+  element^.data := table;
+
+  { Add to the front of the list }
+  Hermes_ListAddFront(pal^.tables, element);
+
+  { Return lookup data }
+  Hermes_PaletteGetTable := table^.data;
+
+End;
+
+Procedure Hermes_PaletteInvalidateCache(handle : THermesHandle);
+
+Var
+  element : PHermesListElement;
+  pal : PHermesPalette;
+
+Begin
+  element := Hermes_ListLookup(PaletteList, handle);
+  If element = Nil Then
+    Exit;
+
+  pal := element^.data;
+
+  element := pal^.tables^.first;
+
+  { Invalidate all lookup tables }
+
+  While element <> Nil Do
+  Begin
+    (PHermesLookupTable(element^.data))^.valid := False;
+    element := element^.next;
+  End;
+End;

+ 111 - 0
packages/hermes/src/utility.inc

@@ -0,0 +1,111 @@
+{
+    Free Pascal port of the Hermes C library.
+    Copyright (C) 2001-2003  Nikolay Nikolov ([email protected])
+    Original C version by Christian Nentwich ([email protected])
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+}
+
+{Procedure Hermes_Calculate_Generic_Info(s_r, s_g, s_b, s_a, 
+                                        d_r, d_g, d_b, d_a : int32;
+					info : PHermesGenericInfo);
+Function Hermes_Topbit(mask : int32) : Integer;}
+
+Procedure Hermes_Calculate_Generic_Info(s_r, s_g, s_b, s_a, 
+                                        d_r, d_g, d_b, d_a : Integer;
+					info : PHermesGenericInfo);
+
+Var
+  r_right, g_right, b_right, a_right : Integer;
+
+Begin
+  {Calculate right shift amount for red. If it's <0, then set it to 0
+   and calculate left shift amount}
+  r_right := s_r - d_r;
+  If r_right < 0 Then
+  Begin
+    info^.r_left := -r_right;
+    info^.r_right := 0;
+  End
+  Else
+  Begin
+    info^.r_left := 0;
+    info^.r_right := r_right;
+  End;
+  
+  {Same for green}
+  g_right := s_g - d_g;
+  If g_right < 0 Then
+  Begin
+    info^.g_left := -g_right;
+    info^.g_right := 0;
+  End
+  Else
+  Begin
+    info^.g_left := 0;
+    info^.g_right := g_right;
+  End;
+  
+  {Same for blue}
+  b_right := s_b - d_b;
+  If b_right < 0 Then
+  Begin
+    info^.b_left := -b_right;
+    info^.b_right := 0;
+  End
+  Else
+  Begin
+    info^.b_left := 0;
+    info^.b_right := b_right;
+  End;
+  
+  {Alpha}
+  a_right := s_a - d_a;
+  If a_right < 0 Then
+  Begin
+    info^.a_left := -a_right;
+    info^.a_right := 0;
+  End
+  Else
+  Begin
+    info^.a_left := 0;
+    info^.a_right := a_right;
+  End;
+End;
+
+Function Hermes_Topbit(mask : int32) : Integer;
+
+Var
+  i : Integer;
+
+Begin
+  If mask = 0 Then
+  Begin
+    Hermes_Topbit := 0;
+    Exit;
+  End;
+  i := 0;
+  While (mask And 1) = 0 Do
+  Begin
+    mask := mask Shr 1;
+    Inc(i);
+  End;
+  While (mask And 1) = 1 Do
+  Begin
+    mask := mask Shr 1;
+    Inc(i);
+  End;
+  Hermes_Topbit := i;
+End;