Index: bitnames.ah
===================================================================
--- bitnames.ah	(revision 2365)
+++ bitnames.ah	(working copy)
@@ -111,6 +111,7 @@
 defbit EXP_EXTRADETAILS,	8 // Show more informations in the train detail window.
 defbit EXP_ASYNCMP,			9 // Asynchronous/internet multiplayer
 defbit EXP_RAILVEHMENU,		10 // Adds a rail vehicle menu/window to the depot window
+defbit EXP_ALTSPRITE,		11 // Alternative sprite loading and caching
 enddefbits
 
 
Index: globals.ah
===================================================================
--- globals.ah	(revision 2365)
+++ globals.ah	(working copy)
@@ -342,6 +342,11 @@
 //	objects: newobjects
 ptrvar objectpool
 
+// Pointer to the regular sprite list sorting table
+// usage:
+//	newspritesystem
+ptrvar paTempRegularSpriteList
+
 // Pointer to the temporary (not saved) vehicle data array
 uvard veh2ptr
 
Index: inc/debugprintf.inc
===================================================================
--- inc/debugprintf.inc	(revision 0)
+++ inc/debugprintf.inc	(revision 0)
@@ -0,0 +1,17 @@
+extern patchsprintf, debugout
+
+%macro debugprintf 1-*	// params: text, params...
+	%define %%paramnum %0
+	%define %%textid %1
+	%rep %0-1
+		%rotate -1
+		push %1
+	%endrep 
+	push %%textid
+	call patchsprintf
+	call debugout
+	add esp, %%paramnum*4
+%endmacro
+
+
+

Property changes on: inc\debugprintf.inc
___________________________________________________________________
Added: svn:eol-style
   + native

Index: inc/spritedesc.inc
===================================================================
--- inc/spritedesc.inc	(revision 2365)
+++ inc/spritedesc.inc	(working copy)
@@ -15,7 +15,9 @@
 	.Y2:		resw 1	// 14h
 	.flags:		resw 1	// 16h
 	.linked:	resd 1	// 18h
-	.exsfeature:	resw 1	// 0x1C //only valid with spritelimit patch
+//	.exsfeature:	resw 1	// 0x1C //only valid with spritelimit patch
+	.exsfeature:
+	.exspritelst:	resd 1	// 0x1C
 endstruc
 
 struc linkedspritedesc
@@ -25,7 +27,9 @@
 	.z:		resb 1	// 0x08
 	.unused:	resb 1	// 0x09
 	.next:		resd 1	// 0x0A
-	.exsfeature:	resw 1	// 0x0E //only valid with spritelimit patch
+//	.exsfeature:	resw 1	// 0x0E //only valid with spritelimit patch
+	.exsfeature:
+	.exspritelst:	resd 1	// 0x0E
 endstruc
 
 struc relspritedesc
@@ -33,7 +37,9 @@
 	.xoffset:	resw 1	// 0x04
 	.yoffset:	resw 1	// 0x06
 	.next:		resd 1	// 0x08
-	.exsfeature:	resw 1	// 0x0C //only valid with spritelimit patch
+//	.exsfeature:	resw 1	// 0x0C //only valid with spritelimit patch
+	.exsfeature:
+	.exspritelst:	resd 1	// 0x0C
 endstruc
 	
 struc groundspritedesc
@@ -43,5 +49,7 @@
 	.y:		resw 1	// 0x0A
 	.z:		resb 1	// 0x0C
 	.unused:	resb 1	// 0x0D
-	.exsfeature:	resw 1	// 0x0E //only valid with spritelimit patch
+//	.exsfeature:	resw 1	// 0x0E //only valid with spritelimit patch
+	.exsfeature:
+	.exspritelst:	resd 1	// 0x0E
 endstruc
Index: inc/spriteheader.inc
===================================================================
--- inc/spriteheader.inc	(revision 2365)
+++ inc/spriteheader.inc	(working copy)
@@ -18,6 +18,7 @@
 	// new entries here
 	.padding:		resb 3	
 	.pseudoflag:		resb 1		// 0x58 = realsprite, 0x59 = pseudosprite
+	.previousspriteptr:	resd 1
 	// don't touch the follwing entries:
 	.spritenumber:		resd 1
 	.size:			resd 1
Index: inc/std.inc
===================================================================
--- inc/std.inc	(revision 2365)
+++ inc/std.inc	(working copy)
@@ -22,3 +22,26 @@
 %endmacro
 %endif
 
+
+// C Calling convention
+// aligns stack on a 4 byte boundry
+//
+// uses: eax, ebx, ecx, edx
+//
+%ifndef c_call
+%macro c_call 1-*.nolist
+	mov ebx, esp
+	and esp, byte ~ 3
+	%define %%target %1
+//	%define %%params %0-1
+	%rep %0-1
+		%rotate -1
+		push %1
+	%endrep
+	call %%target
+//	add esp, %%params*4
+	mov esp, ebx
+%endmacro
+%endif
+
+
Index: inc/ttdvar.inc
===================================================================
--- inc/ttdvar.inc	(revision 2365)
+++ inc/ttdvar.inc	(working copy)
@@ -242,6 +242,8 @@
 ttdvar(curdecoderuntype,0x9c581)		// B: current LZ77 run type
 ttdvar(curfileblocksize,0x7722e)		// W: size of current file buffer
 
+ttdvar(havegroundsprites, 0x9ecdd)	// B: 0/1 Groundsprite was collected
+
 ttdvar(keypresstable,0x9c476)		// Array for all keys; 0=pressed, 80h=not pressed
 ttdvar(shiftedkeyasciitable,0x9f70f)	// Array of ASCII codes to generate for each key, with shift
 ttdvar(regkeyasciitable,0x9f78f)	// Array of ASCII codes to generate for each key, without shift
@@ -326,6 +328,8 @@
 ttdvar(canrandomizelandscape, 0x9ef2a)	// B: 1 = randomize landscape is safe
 ttdvar(autosavesetting, 0x9ef2C)		// B: autosave setting 0=off, 1=3Months, 2=6Months, 3=12Months
 
+ttdvar(usepredefinedmanagerfaces,0x9ef2f) // B:
+
 ttdvar(selectedairporttype, 0x9ede2)	// B: currently selected airport type
 ttdvar(airporttypeavailmask, 0x7710b)	// B: bit mask of available old airport types
 
Index: inc/veh.inc
===================================================================
--- inc/veh.inc	(revision 2365)
+++ inc/veh.inc	(working copy)
@@ -36,7 +36,11 @@
 	.owner: 	resb 1	// 25h:vehicle owner
 	.XY: 		resw 1	// 26h:index into landscape array
 	.cursprite: 	resw 1	// 28h:current sprite ID (incl. direction and veh. type)
-	.box_coord:	resw 4	// 2ah,2ch,2eh,30h:x1,x2,y1,y2 coordinates of sprite box on screen
+	.box_coord:		// 2ah,2ch,2eh,30h:x1,x2,y1,y2 coordinates of sprite box on screen
+	.box_coord.x1:	resw 1	// 2ah:x1
+	.box_coord.x2:	resw 1	// 2ch:x2
+	.box_coord.y1:	resw 1	// 2eh:y1
+	.box_coord.y2:	resw 1	// 30h:y2
 	.vehstatus: 	resw 1	// 32h:bit 0=vehicle invisible (in tunnel/depot), bit 1=stopped, bit 7=crashed, ??
 	.speed: 	resw 1	// 34h:current speed in mph/1.6 (trains), mph/3.2 (rv/ships), see also trnspd.asm
 	.speedfract: 	resb 1	// 36h:current speed, fractional part
@@ -188,6 +192,7 @@
 	.pad:		resb 1
 	.prevptr:	resd 1	// linked list of vehicles queued-for-reserving
 	.nextptr:	resd 1	// pointers point to veh2 struct
+	.spriteblockptr	resd 1	// pointer to the current spriteblock
 		align 4,resb 1
 endstruc
 
Index: lang/english.h
===================================================================
--- lang/english.h	(revision 2365)
+++ lang/english.h	(working copy)
@@ -618,6 +618,7 @@
 BIT(extradetails,  "Show more specs in the vehicle details window")
 BIT(asyncmp,       "Internet multiplayer support")
 BIT(railvehmenu,   "Rail vehicle menu/window in the depot window")
+BIT(altsprite,     "Alternative sprite loading and caching")
 
 // Description for maskdisasters bits
 BITSWITCH(maskdisasters)
Index: Makefile
===================================================================
--- Makefile	(revision 2365)
+++ Makefile	(working copy)
@@ -50,6 +50,10 @@
 	EXTRADEFS += DEBUGNETPLAY=1
 endif
 
+ifdef DEBUGSPRITESTORE
+	EXTRADEFS += DEBUGSPRITESTORE=1
+endif
+
 WDEF_d = WINTTDX=0
 WDEF_w = WINTTDX=1
 WDEF_l = WINTTDX=0
Index: non-asm/md5sum.c
===================================================================
--- non-asm/md5sum.c	(revision 2365)
+++ non-asm/md5sum.c	(working copy)
@@ -523,3 +523,19 @@
 //----------------------------------------------------------------------------
 //--------end of md5.c
 //----------------------------------------------------------------------------
+
+
+struct md5_ctx md5_ctx_shared;
+
+void md5_shared_buffer_start()
+{
+  md5_init_ctx(&md5_ctx_shared);
+}
+void md5_shared_buffer_process(const char *buffer, size_t len)
+{
+  md5_process_bytes(buffer, len, &md5_ctx_shared);
+}
+void *md5_shared_buffer_end(void *resblock) 
+{
+  return md5_finish_ctx(&md5_ctx_shared, resblock);
+}
Index: patches/catchgpf.asm
===================================================================
--- patches/catchgpf.asm	(revision 2365)
+++ patches/catchgpf.asm	(working copy)
@@ -734,6 +734,7 @@
 ; endp hexnibbles 
 
 	// print ebx byte values from ds:esi
+global hexbytes
 hexbytes:
 	mov cl,0
 	call checkbounds
Index: patches/debugout.asm
===================================================================
--- patches/debugout.asm	(revision 0)
+++ patches/debugout.asm	(revision 0)
@@ -0,0 +1,220 @@
+#include <defs.inc>
+#include <var.inc>
+#include <ttdvar.inc>
+#include <pusha.inc>
+#if WINTTDX
+#include <win32.inc>
+#endif
+
+uvarb debugoutbuffer, 2048
+uvard debugoutbuffer_len
+
+svard debugout_hnd
+var debugout_filename
+	db "debuglog.txt",0
+
+exported debugout
+	pusha
+	cmp word [debugout_hnd], -1
+	jne .openok
+#if WINTTDX
+	// we assume here that the jump table is valid in all windows versions
+	extern int21handler
+	mov dword [int21handler], 0x401136
+#endif
+
+	mov edx, debugout_filename
+	xor ecx, ecx
+	mov ax, 0x3c00		//create file
+	push ebp
+	mov ebp, esp
+	and esp, byte ~ 3
+	CALLINT21
+	mov esp, ebp
+	pop ebp
+	jc .leave
+	mov word [debugout_hnd], ax
+.openok:
+	mov ecx, [debugoutbuffer_len]
+	mov edx, debugoutbuffer
+	mov bx, [debugout_hnd]
+	mov ax, 0x4000
+	
+	mov ebp, esp
+	and esp, byte ~ 3
+	CALLINT21
+	mov esp, ebp
+
+.leave:
+	popa
+	ret
+
+	
+// on stack:
+// 	parameters in reverse order
+// 	textid
+// sets:
+//	debugoutbuffer
+//	debugoutbuffer_len
+// uses: nothing
+//       caller responsible to clean stack
+//
+// supports:
+// %P<word size> = Pointer to data output as hex bytes
+// %h1, %h2, %h4 = byte,word or dword printed as hex
+// %u1, %u2, %u4 = byte,word or dword pinted as unsigned decimal
+// %i1, %i2, %i4 = byte,word or dword pinted as signed decimal
+// %s = pointor to a null terminated string
+exported patchsprintf
+ 	pusha
+ 	mov ebp, esp
+	add ebp, _pusha_size+8
+	
+	mov esi, [ebp-4]
+	mov edi, debugoutbuffer	
+.loop:
+	lodsb
+	cmp al, 0
+	je .done
+	
+	cmp al, '%'
+	jne .copy
+	
+.parameter:
+	lodsb
+	cmp al, 'P'
+	je near .dopointed
+	cmp al, 'h'
+	je .dovaluehex
+	cmp al, 'i'
+	je .dovalue_signed
+	cmp al, 'u'
+	je .dovalue_unsigned
+	cmp al, 's'
+	je near .dostrcpy
+.copy:
+.fail:
+	stosb
+	jmp .loop
+.done:
+	// calc size
+	mov byte [edi], 0 
+	mov ecx, edi
+	sub ecx, debugoutbuffer
+	mov [debugoutbuffer_len], ecx
+	popa
+	ret
+
+.dovaluehex:
+	lodsb
+	cmp al, '0'
+	jle .fail
+	cmp al, '4'
+	jg .fail
+	
+	mov cl, al
+	sub cl, '0'
+	shl cl, 1
+	mov eax, [ebp]
+	push edx
+	extcall hexnibbles
+	pop edx
+	add ebp, 4
+	jmp near .loop
+
+.dovalue_signed:
+	mov eax, [ebp]
+	mov cl, [esi]
+	inc esi
+	cmp cl, '4'
+	je .dword_signed
+	cmp cl, '2'
+	je .word_signed
+	movsx eax, al
+.word_signed:
+	movsx eax, ax
+.dword_signed: 
+	call itoa.signed
+	add ebp, 4
+	jmp near .loop	
+
+.dovalue_unsigned:
+	mov eax, [ebp]
+	mov cl, [esi]
+	inc esi
+	cmp cl, '4'
+	je .dword_usigned
+	cmp cl, '2'
+	je .word_usigned
+	movzx eax, al
+.word_usigned:
+	movzx eax, ax
+.dword_usigned:
+	call itoa
+	add ebp, 4
+	jmp near .loop	
+	
+.dopointed:
+	movzx ebx, word [esi]
+	add esi, 2
+	push esi
+	mov esi, [ebp]
+.dopointed_nextbyte:
+	lodsb
+	mov cl,2
+	call hexnibbles
+	mov byte [edi], ' '
+	inc edi
+	dec ebx
+	jnz .dopointed_nextbyte
+	pop esi
+	dec edi
+	add ebp, 4
+	jmp near .loop
+	
+ .dostrcpy:
+ 	push esi
+	mov esi, [ebp]
+ .dostrcpy_loop:
+	lodsb
+	stosb
+	or al, al
+	jnz .dostrcpy_loop
+	pop esi
+	dec edi
+ 	add ebp, 4
+	jmp near .loop
+	
+	
+itoa.signed:
+	or eax, eax
+	jns .nosign
+	mov byte [edi], '-'
+	inc edi
+	neg eax
+.nosign:
+itoa:
+	// in: eax
+	// out: edi
+	// uses: ebx, ecx, eax
+	push ebx
+	push edx
+	mov ebx, 10
+	xor ecx, ecx
+	
+.loop:
+	xor edx, edx
+	div ebx
+	push edx
+	inc ecx
+	cmp eax, 0
+	jne .loop
+	
+.write:
+	pop eax
+	add al, '0'
+	stosb
+	loop .write
+	pop edx
+	pop ebx
+	ret

Property changes on: patches\debugout.asm
___________________________________________________________________
Added: svn:eol-style
   + native

Index: patches/enhgui.asm
===================================================================
--- patches/enhgui.asm	(revision 2365)
+++ patches/enhgui.asm	(working copy)
@@ -1027,6 +1027,7 @@
 var textcolortablewithcompany
 #if WINTTDX
 istruc prespriteheader
+	at prespriteheader.pseudoflag, db 0x58
 	at prespriteheader.size, incbin "embedded/tcc_w.dat",2,2
 	at prespriteheader.actionfeaturedata, incbin "embedded/tcc_w.dat",0,2
 iend
Index: patches/grfinit.asm
===================================================================
--- patches/grfinit.asm	(revision 2365)
+++ patches/grfinit.asm	(working copy)
@@ -382,9 +382,16 @@
 	pusha
 	call preinfoapply
 	call setactivegrfs
+	
+	test word [expswitches],EXP_ALTSPRITE
+	jnz .altsprite
+
 	mov dword [numactsprites],baseoursprites
 	call exsresetspritecounts
-
+	jmp short .done
+.altsprite:
+	extcall SpritesResetToDefault
+.done:
 	extern grfstage
 	mov eax,PROCALL_RESERVE
 	mov byte [grfstage+1],1
@@ -647,6 +654,11 @@
 	// that way TTD will use its own graphics again
 	// in the scenario/savegame currently being loaded
 
+	
+	// But we don't need to do it when we use our new sprite system
+	test word [expswitches],EXP_ALTSPRITE
+	jnz .done
+		
 	mov ebx,[newspritedata]
 	mov ebp,[newspritenum]
 	imul edx,ebp,19
@@ -952,6 +964,7 @@
 
 var oslashglyph1
 istruc prespriteheader
+	at prespriteheader.pseudoflag, db 0x58
 	at prespriteheader.size, incbin "embedded/oslash1.dat",2,2
 	at prespriteheader.actionfeaturedata, incbin "embedded/oslash1.dat",0,2
 iend
@@ -960,6 +973,7 @@
 	
 var oslashglyph2
 istruc prespriteheader
+	at prespriteheader.pseudoflag, db 0x58
 	at prespriteheader.size, incbin "embedded/oslash2.dat",2,2
 	at prespriteheader.actionfeaturedata, incbin "embedded/oslash2.dat",0,2
 iend
Index: patches/grfload.asm
===================================================================
--- patches/grfload.asm	(revision 2365)
+++ patches/grfload.asm	(working copy)
@@ -13,6 +13,7 @@
 #include <house.inc>
 #include <spriteheader.inc>
 
+
 extern calloc,copyspriteinfofn,curfileofsptr,curspriteblock,decodespritefn
 extern dummygrfid,exscurfeature,exsfeaturemaxspritesperblock
 extern exsfeatureuseseparatesprites,exsnumactspritesindex
@@ -1301,7 +1302,25 @@
 	test dword [miscmodsflags],MISCMODS_SMALLSPRITELIMIT
 	jz .exsenabled
 	jmp insertactivespriteblock
+
+.alternativespritesystem:
+	// We don't do any real insert anymore, so we can't fail anymore because of to many sprites in general,
+	// but we should fail if we reached more then 11483 sprites
+	movzx eax, byte [exscurfeature]
+	
+	mov [curextragrm+GRM_EXTRA_SPRITES*4+eax*4],edx
+	
+	mov eax, edi
+	cmp ecx, 0x3FFF
+	jnb short .toomany
+	add edi, ecx
+	// return spriteid as in the grf
+	ret
+
 .exsenabled:
+	test word [expswitches],EXP_ALTSPRITE
+	jnz .alternativespritesystem
+	
 	movzx eax, byte [exscurfeature]	// get the feature ID, stored before
 
 	push edi
@@ -1499,13 +1518,32 @@
 
 global overrideembeddedsprite,overridesprite
 overrideembeddedsprite:
-	mov ch,0
+	movzx ecx, cl
 	mov eax, dword [esi+prespriteheader.size]
 	mov edi, dword [esi+prespriteheader.actionfeaturedata]	// spritenumber
 	add esi, prespriteheader_size
+	test word [expswitches],EXP_ALTSPRITE
+	jnz .altpritesystem_embedded
 	stc
 	jmp short overridesprite.do
 
+.altpritesystem_embedded:	
+	mov ebx, [newspritedata]
+	mov ebp, [ebx+edi*4]
+	cmp ebp, 0
+	jz .noold
+	
+	cmp dword [_prespriteheader(ebp,size)], ecx
+	jge .skip
+.noold:
+.overwrite_embedded:
+	mov [ebx+edi*4], esi
+.skip:
+	add esi, eax
+	ret
+
+
+
 overridesprite:
 	clc
 .do:
@@ -1524,6 +1562,9 @@
 	ret
 
 .overwrite:
+	test word [expswitches],EXP_ALTSPRITE
+	jnz .alternativespritesystem
+
 	cmp dword [ebx+edi*4],0	// is it currently in the cache?
 	je .notincache
 
@@ -1556,7 +1597,20 @@
 
 	add esi,ecx
 	ret
+	
+// EXP_ALTSPRITE
+// in:	eax=sprite data size including header
+//	edi=sprite number
+//	esi=>sprite data
+// out: esi=>after sprite data
+.alternativespritesystem:
+	mov ebx,[newspritedata]
+	mov [ebx+edi*4], esi
+	add esi, eax
+	ret
 
+
+
 // reload sprite info of sprite that had override
 //
 // in:	edi=sprite number
Index: patches/grfsprite.asm
===================================================================
--- patches/grfsprite.asm	(revision 0)
+++ patches/grfsprite.asm	(revision 0)
@@ -0,0 +1,1420 @@
+// Routines for new TTDPatch handling of sprites, cache, drawing
+// Planed features:
+// - all grfs get loaded once
+// - no cache handling, all sprites are in memory
+// currently needs patchsetspritecache, patchmovespriteinfo
+
+#include <std.inc>
+#include <grf.inc>
+#include <flags.inc>
+#include <veh.inc>
+#include <spriteheader.inc>
+#include <spritedesc.inc>
+#include <misc.inc>
+#include <proc.inc>
+#include <pusha.inc>
+
+#include <debugprintf.inc>
+
+
+extern newspritedata
+
+extern malloc
+extern int21handler
+
+
+extern openfilefn, readwordfn, copyspriteinfofn, decodespritefn
+
+
+// For sorting sprites on screen we need some temporay memory markers:
+// we use relocations as the sprite sorting routines need to be fast
+
+%assign NREGULARSPRITESINLIST 750
+%assign NREGULARSPRITESINLISTSIZE 750*4
+
+// Pointer to the regular sprite list sorting table
+// usage:
+//	newspritesystem
+ptrvardec paTempRegularSpriteList
+ptrvarofs pTempRegularSpriteListEnd,paTempRegularSpriteList,NREGULARSPRITESINLISTSIZE
+ptrvarofs pTempSpriteListEnd,paTempRegularSpriteList,NREGULARSPRITESINLISTSIZE+4
+ptrvarofs pTempSpriteListHighMark,paTempRegularSpriteList,NREGULARSPRITESINLISTSIZE+8
+ptrvarofs pTempFirstTextEffectDesc,paTempRegularSpriteList,NREGULARSPRITESINLISTSIZE+12
+ptrvarofs pTempLastTextEffectDesc,paTempRegularSpriteList,NREGULARSPRITESINLISTSIZE+16
+ptrvarofs pTempFirstGroundSpriteDesc,paTempRegularSpriteList,NREGULARSPRITESINLISTSIZE+20
+ptrvarofs pTempLastGroundSpriteDesc,paTempRegularSpriteList,NREGULARSPRITESINLISTSIZE+24
+ptrvarofs pTempLastSpriteInSubList,paTempRegularSpriteList,NREGULARSPRITESINLISTSIZE+28	// used by Class 4 drawing too
+ptrvarofs wTempIsLastSpriteLinked,paTempRegularSpriteList,NREGULARSPRITESINLISTSIZE+32
+
+varb TTDGRFNames
+#if WINTTDX
+.default:
+	db 'TRG1R.GRF',0
+.intro:
+	db 'TRGIR.GRF',0
+.artic:
+	db 'TRGCR.GRF',0
+.tropical:
+	db 'TRGHR.GRF',0
+.toyland:
+	db 'TRGTR.GRF',0
+#else	
+.default:
+	db 'TRG1.GRF',0
+.intro:
+	db 'TRGI.GRF',0
+.artic:
+	db 'TRGC.GRF',0
+.tropical:
+	db 'TRGH.GRF',0
+.toyland:
+	db 'TRGT.GRF',0
+#endif
+endvar
+
+vard ttdgrfnames
+	dd TTDGRFNames.default
+	dd TTDGRFNames.intro
+	dd TTDGRFNames.artic
+	dd TTDGRFNames.tropical
+	dd TTDGRFNames.toyland
+endvar
+
+vard ttdgrfsizes
+	dd 4793	// DOS: 4787 Win: 4793
+	dd 103  // intro 
+	dd 343  // artic
+	dd 558  // tropic
+	dd 1195	// toyland
+endvar
+
+uvard previoussprite
+
+
+uvard ttdgrfspritelst, 6
+uvard ttdgrfreplacementtables, 3*2
+
+
+
+varb logspritetexts
+	.outofmemory db "%s: Out of memory at sprite %i4",13,10,0
+	.tomanysprites db "%s: to many sprites got %i4 but wanted %i4",13,10,0
+	
+	.number db "%s: Sprite %u4 -----",13,10,0
+	.pointer db "@ %u4 / -----",13,10,0
+	.pseudo db 0x09,"pseudosprite: compression %h1, size=%u4",13,10,0
+	.realsprite: db 0x09,"realsprite: header=%P"
+		dw spriteheader_size
+		db ", compressionbyte %h1, w=%u2, h=%u1, xoffset=%i2, yoffset=%i2",13,10,0
+	.readword: db "Read word @ %u4 = %h2",13,10,0
+	.readbyte: db "Read byte @ %u4 = %h2",13,10,0
+	.fillbuffer: db "GRFFillBuffer: new len = %i4",13,10,0
+	
+	
+	.prespriteheader db "PreSpriteHeader: preptr=%h4, size=%i4, pseudo=%h1",13,10,0
+	.showlen: db "len = %i4",13,10,0
+	.createspritelist: db "List %u4, ptr=%h4, previous=%h4",13,10,0
+	
+	.md5sum: db "MD5SUM: %s %P"
+		dw 16
+		db " ",13,10,0
+endvar
+
+
+exported AllocateSpriteCacheNew
+	mov word [spritecacheselector], ds
+	pusha
+// We load all Sprites into memory
+	xor ebp, ebp
+.nextgrf:	
+	mov edx, dword [ttdgrfnames+ebp*4]
+	mov ecx, dword [ttdgrfsizes+ebp*4]
+	
+	call GRFLoader
+	
+	mov dword [ttdgrfspritelst+ebp*4], edi
+	
+	inc ebp
+	cmp ebp, 5
+	jb .nextgrf
+	
+	CHECKMEM
+// Load embedded sprites
+	
+	popa	
+	
+	
+	call InitializeSpriteSystem
+	ret
+
+exported InitializeSpriteSystem
+	inc word [wgraphicssemaphore]
+	call SpritesResetToDefault
+	dec word [wgraphicssemaphore]
+	ret
+
+
+exported SpritesResetToDefault
+	pusha
+	extern numactsprites
+	mov dword [numactsprites],baseoursprites
+	extcall exsresetspritecounts
+	
+// Add Default TTD Sprites
+	mov esi, dword [ttdgrfspritelst]
+	mov edi, dword [newspritedata]
+.loopdefaults:
+	lodsd
+	or eax, eax
+	jz .loopdefaultsdone
+	stosd
+	jmp .loopdefaults
+.loopdefaultsdone:
+
+// Add Intro
+	mov esi, dword [ttdgrfspritelst+4]
+.loopintro:
+	lodsd
+	or eax, eax
+	jz .loopintrodone
+	stosd
+	jmp .loopintro
+.loopintrodone:
+
+	movzx eax, byte [climate]
+	or eax, eax
+	jz .done
+	
+// Load Climate depending sprites
+	mov esi, [ttdgrfspritelst+4+eax*4]
+	mov edi, dword [newspritedata]
+	mov ebp, [ttdgrfreplacementtables-4+eax*4]
+	xor ebx, ebx
+.nextadditionalsprite:
+	lodsd
+	mov bx, word [ebp]
+	or ebx, ebx
+	jz .loopadditionaldone
+	mov [edi+ebx*4], eax
+	add ebp, 2
+	dec ecx
+	jnz .nextadditionalsprite
+.loopadditionaldone:
+
+
+.done:
+	mov ebp, [newspritedata]
+	mov [exspritelst], ebp
+	
+	extern patchflags
+	testflags generalfixes
+	jnc .dontswap
+	// swap monorail and maglev tunnels; #2435 and #2436
+	rol dword [newspritedata+2435*2],16
+.dontswap:
+	popa
+	
+	CHECKMEM
+	ret
+
+
+// Load a TTD grf into memory (datasegment), 
+// in:
+//	edx = filename
+//	ecx = spritelstmax
+// out:
+//	edi = pointer to spritelist
+//	ecx = numsprites
+// uses: anything except ebp
+
+proc GRFLoader
+	local filename, spritelstpointer, spritelstmax
+	local numsprites, len, curptr, pseudo
+	
+	_enter
+	mov [%$spritelstpointer], edi
+	mov [%$spritelstmax], ecx
+	
+	mov dword [%$numsprites], 0
+	mov [%$filename], edx
+	extern curgrffile
+	mov [curgrffile], edx
+	
+	// edx = pointer to filename
+	call GRFFileLoad
+	jc near .fileopenfailed
+		
+	mov dword [previoussprite], 0xdeedbeef
+.nextsprite:
+
+#if DEBUGSPRITESTORE
+	mov edx, dword [%$numsprites]
+	debugprintf logspritetexts.number, dword [%$filename], edx
+#endif
+	call GRFFileGetSprite
+	test edx, edx
+	jz .closefile
+	
+	inc dword [%$numsprites]
+	mov esi, [%$numsprites]
+	cmp esi, [%$spritelstmax]
+	ja near .toomany	
+
+#if DEBUGSPRITESTORE
+	debugprintf logspritetexts.pointer, edi
+	debugprintf logspritetexts.prespriteheader, dword [edi-prespriteheader_size+prespriteheader.previousspriteptr], dword [edi-prespriteheader_size+prespriteheader.size], dword [edi-prespriteheader_size+prespriteheader.pseudoflag]
+#endif
+	
+	// edi = pointer to spritedata
+	// edx = sprite size
+	jmp .nextsprite
+	
+.closefile:
+	call GRFFileClose
+
+#if DEBUGSPRITESTORE
+	debugprintf logspritetexts.md5sum, dword [%$filename], GRFFile_md5sum
+#endif
+	
+	
+.createspritelst:
+// we now create the spritelist
+	mov ecx, dword [%$numsprites]
+	cmp ecx, 0
+	je .done
+	
+	cmp edx, 0
+	jne .lastspriteok
+	mov edi, [previoussprite]
+.lastspriteok:
+	
+	// esi will be used to travese sprites backwards...
+	mov esi, ecx
+	inc ecx	// for zero terminator
+	shl ecx, 2
+	push ecx
+	call GRFAlloc
+	pop eax
+	jc .outofmem
+	
+	mov dword [%$spritelstpointer], eax
+	mov dword [eax+esi*4], 0	// zero terminated
+.nextinspritelst:
+	dec esi
+	#if DEBUGSPRITESTORE
+		debugprintf logspritetexts.createspritelist, esi, edi, dword [edi-prespriteheader_size+prespriteheader.previousspriteptr]
+	#endif
+	mov [eax+esi*4],edi
+	mov edi, dword [edi-prespriteheader_size+prespriteheader.previousspriteptr]
+	
+	cmp esi, 0
+	jnz .nextinspritelst
+
+.done:
+	mov edi, dword [%$spritelstpointer]
+	mov ecx, dword [%$numsprites]
+	_ret
+
+.fileopenfailed:
+	//TODO: add more usefull error message
+	mov edx, [%$filename]
+	
+	
+	extcall criticalerror
+	_ret
+	
+.outofmem:
+	mov edx, [%$filename]
+	call criticalerror
+	_ret
+.toomany:
+	//TODO: add more usefull error message
+	mov edx, [%$filename]
+	call criticalerror
+	_ret
+endproc
+
+
+// Reads the whole sprite with header and returns a spriteptr
+// A sprite can be: (uncompressed or compressed) tile compressed or plain
+// Out: 
+//	edi = pointer to spritedate (always decompressed)
+//	edx = sprite size (always as in memory)
+// uses: -
+uvarb tempspriteheader, spriteheader_size
+
+GRFFileGetSprite:
+	pusha
+	xor eax, eax
+	xor ebx, ebx
+	
+	call GRFFileReadNextWord
+	jc near .fail
+	
+#if DEBUGSPRITESTORE
+	debugprintf logspritetexts.showlen, eax
+#endif
+	mov edx, eax
+	test eax, eax
+	jz near .nomoresprites
+	call GRFFileReadNextByte
+	jc .fail
+	
+	cmp al, 0xFF
+	jne near .decompressgetsize
+	
+#if DEBUGSPRITESTORE
+	debugprintf logspritetexts.pseudo, eax, edx
+#endif
+	
+.pseudo:
+	mov [esp+_pusha.edx], edx
+	mov ecx, edx
+	add ecx, prespriteheader_size
+	push ecx
+	call GRFAllocSprite
+	pop edi
+	jc .nomorememory
+	add edi, prespriteheader_size
+	
+	mov esi, [previoussprite]
+	mov dword [edi-prespriteheader_size+prespriteheader.previousspriteptr], esi
+	mov dword [edi-prespriteheader_size+prespriteheader.size], edx
+	mov byte [edi-prespriteheader_size+prespriteheader.pseudoflag], 0x59
+	mov [previoussprite], edi
+	mov [esp+_pusha.edi], edi
+	
+	or edi, edi
+	jz .failnomem
+	
+	mov ecx, edx
+	// edi = pointer
+	// ecx = count
+	call GRFFileRead
+	jc .error
+	
+	popa
+	clc
+	ret
+	
+.nomoresprites:
+	mov dword [esp+_pusha.edx], 0
+	mov dword [esp+_pusha.edi], 0
+	popa
+	clc
+	ret
+
+.fail:
+	mov dword [esp+_pusha.edx], 0
+	mov dword [esp+_pusha.edi], 0
+	popa
+	stc
+	ret
+	
+// Add sane error handling
+.failbrokenencoding:
+.failnomem:
+.nomorememory:
+
+
+.error:
+	popa
+	xor edx, edx
+	stc
+	ret
+
+.decompressgetsize:
+	// al = info byte
+	// edx = size as read
+	
+	// read the sprite header
+	mov edi, tempspriteheader
+	mov [edi], al
+	inc edi
+	
+	mov ecx, spriteheader_size-1
+	call GRFFileRead
+	jc .error
+	cmp dword [GRFFileReadBufferLen], 0
+	jc .error
+	
+	
+#if DEBUGSPRITESTORE
+	debugprintf logspritetexts.realsprite, tempspriteheader, dword [tempspriteheader+spriteheader.flags], dword [tempspriteheader+spriteheader.width], dword [tempspriteheader+spriteheader.height], dword [tempspriteheader+spriteheader.xoffset], dword [tempspriteheader+spriteheader.yoffset]
+#endif
+	
+	test byte [tempspriteheader+spriteheader.flags], SPRITE_LATEDECOMPRESS
+	jz .sizeok
+	
+	test byte [tempspriteheader+spriteheader.flags], SPRITE_CTILE
+	jnz .failbrokenencoding
+	
+	and byte [tempspriteheader+spriteheader.flags], ~SPRITE_LATEDECOMPRESS
+	
+	// Calc size of decompressed data
+	
+	movzx ebx, byte [tempspriteheader+spriteheader.height]
+	movzx eax, word [tempspriteheader+spriteheader.width]
+	
+	mul bx
+	
+	shl edx, 16
+	add edx, eax
+	// now edx = width * height
+	
+	
+	add edx, spriteheader_size
+.sizeok:
+	// edx = decompressed size (including sprite header)
+	mov [esp+_pusha.edx], edx
+	mov ecx, edx
+	add ecx, prespriteheader_size
+	push ecx
+	call GRFAllocSprite
+	pop edi
+	jc .nomorememory
+
+	add edi, prespriteheader_size
+	
+	mov esi, [previoussprite]
+	mov dword [edi-prespriteheader_size+prespriteheader.previousspriteptr], esi
+	mov dword [edi-prespriteheader_size+prespriteheader.size], edx
+	mov byte [edi-prespriteheader_size+prespriteheader.pseudoflag], 0x58
+	mov [previoussprite], edi
+	mov [esp+_pusha.edi], edi
+	
+	mov esi, tempspriteheader
+	mov ecx, spriteheader_size
+	rep movsb
+
+	sub edx, spriteheader_size
+
+.nextchunk:
+	or edx, edx
+	jz .endofdata
+	
+	xor eax, eax
+	call GRFFileReadNextByte
+	
+	or al, al
+	js .earlierdata
+	// straight data copy
+
+	sub edx, eax
+	mov ecx, eax
+	call GRFFileRead
+	
+	jmp .nextchunk
+.earlierdata:
+	// earlier data
+	
+	movzx ecx, al
+	sar cl, 3
+	neg cl
+	and ecx, 0xFF
+	// now ecx = length
+	
+	mov ah, al
+	and ah, 7
+	call GRFFileReadNextByte
+	movzx eax, ax
+	
+	// now:	eax = offset
+	//	ecx = len
+	sub edx, ecx
+	
+	// copy data
+	mov esi, edi
+	sub esi, eax
+	
+	cmp esi, [previoussprite]
+	jb .errorpointerwrong
+	
+	rep movsb
+	jmp .nextchunk
+
+.endofdata:
+	popa
+	clc
+	ret
+.errorpointerwrong:
+	UD2
+	popa
+	stc
+	ret
+	
+GRFAlloc:
+	jmp malloc
+
+GRFAllocSprite:
+	jmp malloc
+	
+GRFReleaseSprite:
+	CALLINT3
+	ret
+	
+
+%define GRFFileReadBufferSize 0x200
+uvarb GRFFileReadBuffer, GRFFileReadBufferSize
+uvard pGRFFileReadBuffer
+uvard GRFFileReadBufferLen
+
+uvard GRFFile_md5sum, 8
+
+
+// Load a GRF File
+// in:
+// edx = filenameptr
+// out:
+// carry flag set if error
+GRFFileLoad:
+	pusha
+	mov word [curfileblocksize], 0
+	call dword [openfilefn]
+	jc .error
+	mov word [tempspritefilehandle], bx
+	mov dword [GRFFileReadBufferLen], 0 
+	call GRFFileRewind
+	extern _md5_shared_buffer_start
+	c_call _md5_shared_buffer_start
+	popa
+	clc
+	ret
+.error:
+	popa
+	stc
+	ret
+
+	
+	
+GRFFileClose:
+	pusha
+	mov ax, 0x3e00
+	mov bx, [tempspritefilehandle]
+	CALLINT21
+	
+	// maybe we need to read some remaining bytes to get the right md5sum
+	call GRFFileFillBuffer
+	
+	extern _md5_shared_buffer_end, 
+	c_call _md5_shared_buffer_end, GRFFile_md5sum
+	popa
+	ret
+	
+GRFFileFillBuffer:
+	cmp dword [GRFFileReadBufferLen], 0
+	je .readintobuffer
+	ret
+	
+.readintobuffer:
+	pusha
+	mov dword [GRFFileReadBufferLen], 0
+	mov eax, 0x3F00
+	movzx ebx, word [tempspritefilehandle]
+	mov ecx, GRFFileReadBufferSize
+	mov edx, GRFFileReadBuffer
+	mov [pGRFFileReadBuffer], edx
+	CALLINT21
+//	jc .error
+	
+//	cmp ax, 0
+//	je .eof
+	movzx eax, ax
+	mov dword [GRFFileReadBufferLen], eax
+	
+#if DEBUGSPRITESTORE
+	debugprintf logspritetexts.fillbuffer, eax
+#endif
+
+ 	extern _md5_shared_buffer_process, 
+	c_call _md5_shared_buffer_process, GRFFileReadBuffer, eax
+
+	popa
+	clc
+	ret
+	
+.eof:
+	mov dword [GRFFileReadBufferLen], 0
+	popa
+	stc
+	ret
+.error:
+	mov dword [GRFFileReadBufferLen], 0
+	popa
+	stc
+	ret
+	
+		
+// in:
+// ecx = count
+// edi = ptr to store data
+GRFFileRead:
+	push esi
+.next:
+	cmp dword [GRFFileReadBufferLen], 0
+	jz .bufferempty
+	
+	mov esi, dword [pGRFFileReadBuffer]
+	movsb
+	inc dword [pGRFFileReadBuffer]
+	dec dword [GRFFileReadBufferLen]
+	
+	dec ecx
+	jz .done
+	jmp .next
+	
+.done:
+	pop esi
+	clc
+	ret
+
+.bufferempty:
+	call GRFFileFillBuffer
+	jc .error
+	cmp dword [GRFFileReadBufferLen], 0
+	jnz .next
+		
+.error:
+	pop esi
+	stc
+	ret
+
+	
+
+// out:
+// al = read byte
+// carry = not possible
+GRFFileReadNextByte:
+	cmp dword [GRFFileReadBufferLen], 0
+	jz .bufferempty
+.readbyte:
+	push esi
+	mov esi, dword [pGRFFileReadBuffer]
+	lodsb
+#if 0
+	debugprintf logspritetexts.readbyte, dword [pGRFFileReadBuffer], eax
+#endif
+	inc dword [pGRFFileReadBuffer]
+	dec dword [GRFFileReadBufferLen]
+	pop esi
+	clc
+	ret
+	
+.bufferempty:
+	call GRFFileFillBuffer
+	cmp dword [GRFFileReadBufferLen], 0
+	jnz .readbyte
+	stc
+	ret
+
+
+// out:
+// ax = read word
+// carry = not possible
+GRFFileReadNextWord:
+	push esi
+	cmp dword [GRFFileReadBufferLen], 1
+	je .byteleft
+	jl .bufferempty
+	
+.readword:
+
+	mov esi, dword [pGRFFileReadBuffer]
+	lodsw
+#if 0
+	debugprintf logspritetexts.readword, dword [pGRFFileReadBuffer], eax
+#endif
+	add dword [pGRFFileReadBuffer], 2
+	sub dword [GRFFileReadBufferLen], 2
+	pop esi
+	clc
+	ret
+	
+.bufferempty:
+	call GRFFileFillBuffer
+	jc .fail
+	cmp word [GRFFileReadBufferLen], 2
+	jge .readword
+.fail:
+	pop esi
+	xor ax, ax
+	stc
+	ret
+	
+.byteleft:
+	mov esi, dword [pGRFFileReadBuffer]
+	mov al, [esi]
+	inc dword [pGRFFileReadBuffer]
+	dec dword [GRFFileReadBufferLen]
+	
+	call GRFFileFillBuffer
+	jc .fail
+	cmp word [GRFFileReadBufferLen], 0
+	je .fail
+	
+.nextbyte:
+	mov esi, dword [pGRFFileReadBuffer]
+	mov ah, [esi]
+#if 0
+	debugprintf logspritetexts.readword, dword [pGRFFileReadBuffer], eax
+#endif
+	inc dword [pGRFFileReadBuffer]
+	dec dword [GRFFileReadBufferLen]
+	pop esi
+	clc
+	ret	
+
+GRFFileRewind:
+	pusha
+	mov dword [GRFFileReadBufferLen], 0
+	xor ecx, ecx
+	xor edx, edx
+	mov eax, 0x4200
+	movzx ebx, word [tempspritefilehandle] 
+	CALLINT21
+	popa
+	ret
+
+
+// In: 
+// ebx = sprite & flags:
+//        bits  0..13: sprite number
+//        bits 14..15: 0 = normal
+//                     1 = partial transparency
+//                     2 = recolor sprite
+//        bits 16..31: special sprite number (only if bits 14 or 15 are set)
+//        the special sprite contains a recoloring map
+// cx, dx = screen X,Y position
+// edi -> screen update block descriptor
+// ebp -> spritelist (if used in extended form, otherwise exspritelst)
+// uses: eax, ebx, esi, edi, ebp
+//
+uvard DrawSpriteNewLastSprite
+uvard DrawSpriteNewLastSpriteListPtr
+
+exported DrawSpriteNew
+	xor ebp, ebp
+	xchg ebp, [exspritelst]
+	or ebp, ebp
+	jnz short DrawSpriteExt	
+	mov ebp, [newspritedata]
+	
+exported DrawSpriteExt
+	xor eax, eax
+	
+	test bx, 0x4000+0x8000
+	jz .normal
+	inc eax		// recolor
+	or bx, bx
+	js .recolor
+.transparent:
+	inc eax
+.recolor:
+	// now ax: 1=recolored, 2=transparent
+	mov esi, ebx
+	shr esi, 16
+	and esi, 0x3FFF
+	shl esi, 2
+	add esi, [newspritedata]
+	
+	mov esi, [esi]
+	inc esi
+	mov word [temprecolormapsprite+4], es
+	mov dword [temprecolormapsprite], esi
+
+.normal:
+	and ebx, 0x3FFF
+	mov esi, ebx
+	
+	mov [DrawSpriteNewLastSprite], ebx
+	mov [DrawSpriteNewLastSpriteListPtr], ebp
+	
+	shl esi, 2
+	add esi, ebp	// newspritedata
+	mov esi, [esi]
+	
+	cmp byte [_prespriteheader(esi, pseudoflag)], 0x58
+	jz .oksprite
+	UD2
+.oksprite:
+	
+	db 0x66
+	mov es, word [spritecacheselector]	// should be the spritecacheselector but it's has to be ds 
+// esi = sprite data
+// edi -> screen update block descriptor
+// cx, dx = screen X,Y position
+// ax = 0: normal, 1: recolored, 2: transparent
+// es = sprite selector
+	extern drawspriteonscreen
+	call [drawspriteonscreen]
+
+	mov dword [DrawSpriteNewLastSprite], 0
+	mov dword [DrawSpriteNewLastSpriteListPtr], 0
+	ret
+	
+
+	
+// Several TTD functions need the sprite data,
+// the follwing functions will replace the lookup code by TTD.
+	
+
+// in: ebx = spriteid
+// out: esi = pointer
+// returns a pointer of spritedata 	
+exported FetchSprite
+	and ebx, 0x3FFF
+	mov esi, ebx
+	
+	shl esi, 2
+	add esi, [newspritedata]
+	mov esi, [esi]
+	ret
+
+exported FetchSpriteSS
+	and ebx, 0x3FFF
+	mov esi, ebx
+	
+	shl esi, 2
+	add esi, [ss:newspritedata]
+	mov esi, [esi]
+	ret
+
+exported FetchSpriteMouseCursor
+	and ebx, 0x3FFF
+	mov esi, ebx
+	shl esi, 2
+	add esi, [newspritedata]
+	mov esi, [esi]
+	
+	//extcall setmousecursorsprite
+	ret
+
+	
+exported GetCharSpriteNew
+	mov esi, ebx
+	shl esi, 2
+	add esi, [newspritedata]
+	mov esi, [esi]
+	ret
+	
+
+// ----------------------- Add*Sprite --------------------
+uvard exspritelst
+
+exported AddGroundSpriteNew
+	mov byte [havegroundsprites], 1
+	mov ebp, [pTempSpriteListEnd]
+	cmp ebp, [pTempSpriteListHighMark]
+	jnb near .nomoreroom
+	add dword [pTempSpriteListEnd], groundspritedesc_size
+
+	mov [ebp+groundspritedesc.sprite], ebx
+	mov dword [ebp+groundspritedesc.next], 0
+	mov [ebp+groundspritedesc.x], ax
+	mov [ebp+groundspritedesc.y], cx
+	mov [ebp+groundspritedesc.z], dl
+
+	xor ebx, ebx
+	xchg ebx, dword [exspritelst]
+	or ebx, ebx
+	jnz .specialsprite
+	mov ebx, [newspritedata]
+.specialsprite:
+	mov dword [ebp+groundspritedesc.exspritelst], ebx
+	
+	xor ebx, ebx
+	xchg ebx, dword [exspritelst]
+	mov [ebp+groundspritedesc.exspritelst], ebx
+	
+	mov ebx, [pTempLastGroundSpriteDesc]
+	or ebx, ebx
+	jz .firstentry
+	
+	mov [ebx+groundspritedesc.next], ebp
+	mov [pTempLastGroundSpriteDesc], ebp
+	ret
+.firstentry:
+	mov [pTempFirstGroundSpriteDesc], ebp
+	mov [pTempLastGroundSpriteDesc], ebp
+
+.nomoreroom:
+	ret
+
+
+// In: ebx = sprite number with flags
+//     ax,cx,dl = X,Y,Z
+//     di,si,dh = X,Y,Z extents
+// Out: dh = 0=added, 1=not added
+// Preserves: AX,CX,DL	
+exported AddSpriteNew
+	mov dword [pTempLastSpriteInSubList], 0
+	mov word [wTempIsLastSpriteLinked], 0
+	mov ebp, [pTempSpriteListEnd]
+	cmp ebp, [pTempSpriteListHighMark]
+	jnb near .error
+	
+	mov [ebp+spritedesc.sprite], ebx
+	
+	
+	// Generate the pixel coordinates and see if they are outside the screenblock description found
+	push eax
+	push ecx
+	push edx
+	push esi
+	push edi
+	
+	and ebx, 0x3FFF
+
+// Fetch the sprite data
+	xor esi, esi
+	xchg esi, dword [exspritelst]
+	or esi, esi
+	jnz .specialsprite
+	mov esi, [newspritedata]
+.specialsprite:
+	mov dword [ebp+spritedesc.exspritelst], esi
+
+	lea esi, [esi+ebx*4]	
+	cmp esi, 0
+	je near .outside	
+	mov esi, [esi]
+	
+
+	
+	xor dh, dh
+	mov bx, ax
+	neg ax
+	add ax, cx
+	add cx, bx
+	shl ax, 1
+	sub cx, dx
+	
+	// ebp = spritedesc
+	// esi = sprite
+	// edi = scrnblockdesc
+	
+	mov edi, [tempvar]
+
+	// generate pixelX1, pixelY1 coordinates
+	add ax, word [esi+spriteheader.xoffset]
+	add cx, word [esi+spriteheader.yoffset]
+		
+	mov [ebp+spritedesc.pixelX1], ax
+	mov [ebp+spritedesc.pixelY1], cx
+	
+	// generate pixelX2, pixelY2 coordinates
+	add ax, word [esi+spriteheader.width]
+	movzx bx, byte [esi+spriteheader.height]
+	add cx, bx
+	
+	mov [ebp+spritedesc.pixelX2], ax
+	mov [ebp+spritedesc.pixelY2], cx
+	
+	// are these coordinates outside?
+	mov bx, word [edi+scrnblockdesc.x]
+	cmp ax, bx
+	jle near .outside
+	add bx, word [edi+scrnblockdesc.width]
+	cmp bx, word [ebp+spritedesc.pixelX1]
+	jle near .outside
+	
+	mov bx, [edi+scrnblockdesc.y]
+	cmp cx, bx
+	jle near .outside
+	add bx, word [edi+scrnblockdesc.height]
+	cmp bx, word [ebp+spritedesc.pixelY1]
+	jle near .outside
+
+	
+	pop edi
+	pop esi
+	pop edx
+	pop ecx
+	pop eax
+	
+	dec di
+	dec si
+	dec dh
+	add di, ax
+	add si, cx
+	add dh, dl
+	
+	
+	mov word [ebp+spritedesc.X1], ax
+	mov word [ebp+spritedesc.Y1], cx
+	mov word [ebp+spritedesc.Z1], dx	// writes Z2 too
+	mov word [ebp+spritedesc.X2], di
+	mov word [ebp+spritedesc.Y2], si
+	
+	mov word [ebp+spritedesc.flags], 0
+	mov dword [ebp+spritedesc.linked], 0
+	
+	
+	mov [pTempLastSpriteInSubList], ebp
+	add dword [pTempSpriteListEnd], spritedesc_size
+	mov edi, [pTempRegularSpriteListEnd]
+	mov dword [edi], ebp
+	mov dword [edi+4], 0
+	add dword [pTempRegularSpriteListEnd], 4
+	xor dh, dh
+	ret
+.outside:
+	pop edi
+	pop esi
+	pop edx
+	pop ecx
+	pop eax
+
+.error:
+	mov dh, 1
+	ret
+	
+	
+exported AddLinkedSpriteNew
+	mov ebp, [pTempSpriteListEnd]
+	cmp ebp, [pTempSpriteListHighMark]
+	jnb near .error
+	
+	mov [ebp+linkedspritedesc.sprite], ebx
+	
+	// Generate the pixel coordinates and see if they are outside the screenblock description found
+	push eax
+	push ecx
+	push edx
+	push esi
+	push edi
+	
+	and ebx, 0x3FFF
+	
+// Fetch the sprite data
+	xor esi, esi
+	xchg esi, dword [exspritelst]
+	or esi, esi
+	jnz .specialsprite
+	mov esi, [newspritedata]
+.specialsprite:
+	mov dword [ebp+linkedspritedesc.exspritelst], esi
+
+	lea esi, [esi+ebx*4]
+	cmp dword [esi], 0
+	jz near .outside
+	
+	mov esi, [esi]
+
+	cmp byte [_prespriteheader(esi, pseudoflag)], 0x58
+	jz .oksprite
+	UD2
+.oksprite:
+	
+	xor dh, dh
+	mov bx, ax
+	neg ax
+	add ax, cx
+	add cx, bx
+	shl ax, 1
+	sub cx, dx
+	
+	
+	mov edi, [tempvar]
+	
+	// generate pixelX1, pixelY1 coordinates
+	add ax, word [esi+spriteheader.xoffset]
+	add cx, word [esi+spriteheader.yoffset]
+	
+	// are these coordinates outside?
+	mov bx, [edi+scrnblockdesc.x]
+	add bx, [edi+scrnblockdesc.width]
+	cmp bx, ax
+	jle near .outside
+	
+	mov bx, [edi+scrnblockdesc.y]
+	add bx, [edi+scrnblockdesc.height]
+	cmp bx, cx
+	jle near .outside
+	
+	// generate pixelX2, pixelY2 coordinates
+	add ax, word [esi+spriteheader.width]
+	movzx bx, byte [esi+spriteheader.height]
+	add cx, bx
+	
+	// are these coordinates outside?
+	cmp ax, [edi+scrnblockdesc.x]
+	jle near .outside
+	cmp cx, [edi+scrnblockdesc.y]
+	jle near .outside
+	
+	pop edi
+	pop esi
+	pop edx
+	pop ecx
+	pop eax
+	
+	mov [ebp+linkedspritedesc.x], ax
+	mov [ebp+linkedspritedesc.y], cx
+	mov [ebp+linkedspritedesc.z], dl
+	mov dword [ebp+linkedspritedesc.next], 0
+	
+	mov ebx, [pTempLastSpriteInSubList]
+	or ebx, ebx
+	jz .error	// we can't link without a real parent sprite...
+	add dword [pTempSpriteListEnd], linkedspritedesc_size
+	
+	mov edi, 1
+	xchg di, [wTempIsLastSpriteLinked]
+	or di, di
+	jnz .lastwaslinked
+	
+	mov [ebx+spritedesc.linked], ebp
+	or word [ebx+spritedesc.flags], 0x80
+	mov [pTempLastSpriteInSubList], ebp
+	xor dh, dh
+	ret
+	
+.lastwaslinked:
+	mov [ebx+linkedspritedesc.next], ebp
+	mov [pTempLastSpriteInSubList], ebp
+	xor dh, dh
+	ret
+	
+.outside:
+	pop edi
+	pop esi
+	pop edx
+	pop ecx
+	pop eax
+.error:
+	mov dh, 1
+	ret
+
+exported AddRelSpriteNew
+	mov ebp, [pTempSpriteListEnd]
+	cmp ebp, [pTempSpriteListHighMark]
+	jnb near .error
+	
+	mov [ebp+relspritedesc.sprite], ebx
+
+	and ebx, 0x3FFF
+// Fetch the sprite data
+
+	xor esi, esi
+	xchg esi, dword [exspritelst]
+	or esi, esi
+	jnz .specialsprite
+	mov esi, [newspritedata]
+.specialsprite:
+	mov dword [ebp+linkedspritedesc.exspritelst], esi
+
+	
+	mov ebx, [pTempLastSpriteInSubList]
+	or ebx, ebx
+	jz .error	// we can't link without a real parent sprite...
+	
+	add dword [pTempSpriteListEnd], relspritedesc_size
+	
+	mov [ebp+relspritedesc.xoffset], ax
+	mov [ebp+relspritedesc.yoffset], cx
+	mov dword [ebp+relspritedesc.next], 0
+	
+	mov edi, 1
+	xchg di, [wTempIsLastSpriteLinked]
+	or edi, edi
+	jnz .lastwasrelative
+	mov [ebx+spritedesc.linked], ebp
+	mov [pTempLastSpriteInSubList], ebp
+	xor dh, dh
+	ret
+.lastwasrelative:
+	mov [ebx+relspritedesc.next], ebp
+	mov [pTempLastSpriteInSubList], ebp
+	xor dh, dh
+	ret
+	
+.error:
+	mov dh, 1
+	ret
+
+// ----------------------- Draw(Ground)Sprites --------------------
+
+exported DrawGroundSpritesNew
+	mov ebp, [pTempFirstGroundSpriteDesc]
+.next:
+	push edi
+	push ebp
+	mov cx, [ebp+groundspritedesc.x]
+	mov dx, [ebp+groundspritedesc.y]
+	
+	// convert to screen coordinates
+	mov bx, cx
+	neg cx
+	add cx, dx
+	add dx, bx
+	shl cx, 1
+	
+	movzx ax, byte [ebp+groundspritedesc.z]
+	sub dx, ax
+	
+	mov ebx, [ebp+groundspritedesc.sprite]
+	mov ebp, [ebp+groundspritedesc.exspritelst]
+	call DrawSpriteExt
+
+	pop ebp
+	pop edi
+	mov ebp, [ebp+groundspritedesc.next]
+	or ebp, ebp
+	jnz .next
+	ret
+
+exported DrawRegularSpritesNew
+	mov esi, paTempRegularSpriteList
+.nextsprite:
+	mov ebp, [esi]
+	or ebp, ebp
+	jz near .done
+
+	push esi
+	push edi
+	push ebp
+	mov cx, [ebp+spritedesc.X1]
+	mov dx, [ebp+spritedesc.Y1]
+	
+	// convert to screen coordinates
+	mov bx, cx
+	neg cx
+	add cx, dx
+	add dx, bx
+	shl cx, 1
+	
+	movzx ax, byte [ebp+spritedesc.Z1]
+	sub dx, ax
+	
+	mov ebx, [ebp+spritedesc.sprite]
+	mov ebp, [ebp+spritedesc.exspritelst]
+	call DrawSpriteExt
+
+	pop ebp
+	pop edi
+	pop esi
+
+	mov esi, [ebp+spritedesc.linked]
+	or esi, esi
+	jnz .relorlinkedsprite
+.getnextsprite:
+	pop esi
+	add esi, 4
+	jmp .nextsprite
+	
+.relorlinkedsprite:
+	test word [ebp+spritedesc.flags], 0x80
+	jnz .linkedsprite
+.relsprite:
+	push esi
+	push edi
+	push ebp
+	mov cx, [esi+relspritedesc.xoffset]
+	mov dx, [esi+relspritedesc.yoffset]
+	add cx, [ebp+spritedesc.pixelX1]
+	add dx, [ebp+spritedesc.pixelY1]
+	
+	mov ebx, [esi+relspritedesc.sprite]
+	mov ebp, [esi+relspritedesc.exspritelst]
+	call DrawSpriteExt
+	
+	pop ebp
+	pop edi
+	pop esi
+	mov esi, [esi+relspritedesc.next]
+	or esi, esi
+	jnz .relsprite
+
+	jmp .getnextsprite
+	
+.linkedsprite:
+	push esi
+	push edi
+	push ebp
+	mov cx, [esi+linkedspritedesc.x]
+	mov dx, [esi+linkedspritedesc.y]
+	
+	// convert to screen coordinates
+	mov bx, cx
+	neg cx
+	add cx, dx
+	add dx, bx
+	shl cx, 1
+	
+	movzx ax, byte [esi+linkedspritedesc.z]
+	sub dx, ax
+	
+	mov ebx, [esi+linkedspritedesc.sprite]
+	mov ebp, [esi+linkedspritedesc.exspritelst]
+	call DrawSpriteExt
+
+	pop ebp
+	pop edi
+	pop esi
+	mov esi, [esi+linkedspritedesc.next]
+	or esi, esi
+	jnz .linkedsprite
+
+	jmp .getnextsprite
+.done:
+	ret
+	
+// ----------------------- Vehicle Code --------------------
+exported UpdateVehicleSpriteboxNew
+	movzx ebp, word [esi+veh.cursprite]
+	and ebp, 0x3FFF
+	push ebp
+
+	mov eax, [esi+veh.veh2ptr]
+	mov eax, [eax+veh2.spriteblockptr]
+	mov ecx, [newspritedata]
+	or eax, eax 
+	jz .nogrfspecificspriteblock
+	mov ecx, eax
+.nogrfspecificspriteblock:
+	
+	mov ebp, [ecx+ebp*4]
+	cmp byte [ebp-prespriteheader_size+prespriteheader.pseudoflag], 0x58
+	je .realsprite
+	// eiyee, we don't have a real sprite!
+	CALLINT3
+	mov ecx, [newspritedata]
+	mov ebp, 0x1	
+	mov ebp, [ecx+ebp*4]
+	
+.realsprite:
+	mov ax, [esi+veh.xpos]
+	mov cx, [esi+veh.ypos]
+	movsx dx, byte [esi+veh.delx]
+	add ax, dx
+	movsx dx, byte [esi+veh.dely]
+	add cx, dx
+	movzx dx, byte [esi+veh.zpos]
+	
+	mov bx, ax
+	neg ax
+	
+	add ax, cx
+	shl ax, 1
+	
+	add cx, bx
+	sub cx, dx
+	
+	add ax, word [ebp+spriteheader.xoffset]
+	add cx, word [ebp+spriteheader.yoffset]
+	
+	extern UpdateBBlockVehicleLists
+	call [UpdateBBlockVehicleLists]
+	
+	mov [esi+veh.box_coord.x1], ax
+	mov [esi+veh.box_coord.y1], cx
+	add ax, word [ebp+spriteheader.width]
+	movzx dx, byte [ebp+spriteheader.height]
+	add cx, dx
+	add ax, 2
+	add cx, 2
+	mov word [esi+veh.box_coord.x2], ax
+	mov word [esi+veh.box_coord.y2], cx
+	pop ebp
+	ret

Property changes on: patches\grfsprite.asm
___________________________________________________________________
Added: svn:eol-style
   + native

Index: patches/morecurr.asm
===================================================================
--- patches/morecurr.asm	(revision 2365)
+++ patches/morecurr.asm	(working copy)
@@ -428,6 +428,7 @@
 // Euro glyph in three font sizes
 var euroglyph1
 istruc prespriteheader
+	at prespriteheader.pseudoflag, db 0x58
 	at prespriteheader.size, incbin "embedded/eurocha1.dat",2,2
 	at prespriteheader.actionfeaturedata, incbin "embedded/eurocha1.dat",0,2
 iend
@@ -435,6 +436,7 @@
 	
 var euroglyph2
 istruc prespriteheader
+	at prespriteheader.pseudoflag, db 0x58
 	at prespriteheader.size, incbin "embedded/eurocha2.dat",2,2
 	at prespriteheader.actionfeaturedata, incbin "embedded/eurocha2.dat",0,2
 iend
Index: patches/newsprit.asm
===================================================================
--- patches/newsprit.asm	(revision 2365)
+++ patches/newsprit.asm	(working copy)
@@ -16,6 +16,7 @@
 #include <idf.inc>
 #include <objects.inc>
 #include <spriteheader.inc>
+#include <bitvars.inc>
 
 extern acttriggers,cachevehvar40x,canalfeatureids,cargoaction3,curcallback
 extern curgrffile,curgrfsprite,curstationtile,curtriggers,ecxcargooffset
@@ -48,6 +49,7 @@
 uvard curgrfid,1,s		// same here
 uvard curaction3info
 uvard mostrecentspriteblock
+uvard mostrecentspritelist,1,s	// must be signed to indicate use default one
 uvarb mostrecentgrfversion
 
 uvard grfvarfeature		// feature to use for 40+x etc. variable handlers
@@ -651,7 +653,11 @@
 		// record file and sprite number for the crash logger
 	mov ebx,[edx+spriteblock.filenameptr]
 	mov [curgrffile],ebx
-
+	
+	// record the most recent sprite list
+	mov ebx,[edx+spriteblock.spritelist]
+	mov [mostrecentspritelist], ebx
+	
 	mov ebx,[eax+action3info.spritenum]
 	mov [curgrfsprite],ebx
 
Index: patches/sprlimit.asm
===================================================================
--- patches/sprlimit.asm	(revision 2365)
+++ patches/sprlimit.asm	(working copy)
@@ -114,10 +114,16 @@
 exsgetspritecount:
 	test dword [miscmodsflags],MISCMODS_SMALLSPRITELIMIT
 	jnz .small
+
+	// The alternative spritesystem uses grf local spritelists...
+	test word [expswitches],EXP_ALTSPRITE
+	jnz .alternativespritesystem
+
 	// well, if you get overexited, this can result in a crash when to much memory seems to be allocated
 	mov ebx, EXTBASE_END + 1
 	ret
 .small:
+.alternativespritesystem:
 	mov ebx, 16384
 	ret
 
Index: patches/tunbridg.asm
===================================================================
--- patches/tunbridg.asm	(revision 2365)
+++ patches/tunbridg.asm	(working copy)
@@ -875,6 +875,7 @@
 
 var enhancetunnelshelpersprite
 istruc prespriteheader
+	at prespriteheader.pseudoflag, db 0x58
 	at prespriteheader.size, incbin "embedded/t_helper.dat",2,2
 	at prespriteheader.actionfeaturedata, incbin "embedded/t_helper.dat",0,2
 iend
Index: patches/vehspri.asm
===================================================================
--- patches/vehspri.asm	(revision 2365)
+++ patches/vehspri.asm	(working copy)
@@ -17,9 +17,11 @@
 #include <player.inc>
 #include <window.inc>
 #include <industry.inc>		// For indu var 45
+#include <bitvars.inc>
 
 extern cargoamountnnamesptr,cargoclass,curgrfid
 extern cargotypes,deftwocolormaps,exscurfeature
+extern exspritelst, mostrecentspritelist // EXP_ALTSPRITE
 extern exsdrawsprite,generatesoundeffect,getnewsprite,getrefitmask,grffeature
 extern initrailvehsorttable,miscgrfvar,newvehdata,patchflags,randomtrigger
 extern showvehinfo.callback,trainspritemove
@@ -43,16 +45,22 @@
 
 	add edi,[orgshipspritebase]
 	add bx,[edi]
+	ret
 .gotit:
 	pushf
 	cmp esi, [esp+8]	// check if we had an esi=edi was the same, then a drawsprite call will follow
-	jne .notadirectdrawingcall	
+	jne .notadirectdrawingcall
+	
 	mov byte [exsdrawsprite], 1
 	mov byte [exscurfeature], 2
+	// EXP_ALTSPRITE
+	mov edi, dword [mostrecentspritelist]
+	mov dword [exspritelst], edi
 .notadirectdrawingcall:
 	popf
 	ret
-
+	
+	
 // same but for trains
 //
 // out:	carry set if TTD needs to do the final three adjustments to bx
@@ -90,12 +98,17 @@
 	xor edi,2
 	pushf
 	cmp esi, [esp+8]	// check if we had an esi=edi was the same, then a drawsprite call will follow
-	jne .notadirectdrawingcall	
+	jne .notadirectdrawingcall
+		
 	mov byte [exsdrawsprite], 1
 	mov byte [exscurfeature], 0
+	// EXP_ALTSPRITE
+	mov eax, dword [mostrecentspritelist]
+	mov dword [exspritelst], eax
 .notadirectdrawingcall:
 	popf
 	ret
+	
 
 // and the road vehicles
 //
@@ -113,13 +126,20 @@
 	mov ax,[esi+veh.capacity]
 	shr ax,1
 	cmp ax,[esi+veh.currentload]
-
+	ret
+	
 .gotit:
 	pushf
 	cmp esi, [esp+8]	// check if we had an esi=edi was the same, then a drawsprite call will follow
 	jne .notadirectdrawingcall	
 	mov byte [exsdrawsprite], 1
 	mov byte [exscurfeature], 1
+	
+	// EXP_ALTSPRITE
+	push eax
+	mov eax, dword [mostrecentspritelist]
+	mov dword [exspritelst], eax
+	pop eax
 .notadirectdrawingcall:
 	popf
 	ret
@@ -187,10 +207,7 @@
 .done:
 	pushf
 	cmp esi, [esp+8]	// check if we had an esi=edi was the same, then a drawsprite call will follow
-	jne .notadirectdrawingcall	
-	mov byte [exsdrawsprite], 1
-	mov byte [exscurfeature], 3
-.notadirectdrawingcall:
+	je .adirectdrawingcall	
 	popf
 	ret
 
@@ -198,6 +215,18 @@
 	add edi,[orgplanespritebase]
 	add bx,[edi]
 	ret
+	
+.adirectdrawingcall:
+	mov byte [exsdrawsprite], 1
+	mov byte [exscurfeature], 3
+	// EXP_ALTSPRITE
+	push eax
+	mov eax, dword [mostrecentspritelist]
+	mov dword [exspritelst], eax
+	pop eax
+.notadirectdrawingcall:
+	popf
+	ret
 
 global getshadowsprite
 getshadowsprite:
@@ -225,10 +254,14 @@
 
 	add ebx,[orgshipspritebase]
 	add ax,[ebx]
-
+	ret
+	
 .gotit:
 	mov byte [exsdrawsprite], 1
 	mov byte [exscurfeature], 2
+	// EXP_ALTSPRITE
+	mov ebp, dword [mostrecentspritelist]
+	mov dword [exspritelst], ebp
 	ret
 
 global displayship_noplayer
@@ -257,10 +290,15 @@
 
 .gotit:
 	add dx,[trainspritemove]
+//	pop ebx
+//	xor ebx,2
+	mov byte [exsdrawsprite], 1
+	mov byte [exscurfeature], 0
+	// EXP_ALTSPRITE
+	mov ebx, dword [mostrecentspritelist]
+	mov dword [exspritelst], ebx
 	pop ebx
 	xor ebx,2
-	mov byte [exsdrawsprite], 1
-	mov byte [exscurfeature], 0
 	ret
 
 global display1stengine_noplayer
@@ -282,10 +320,15 @@
 	and ax,[ebx+2-0x94]
 	add ax,[ebx+2+0x94]
 
+	pop ebx
+	ret
 .gotit:
-	pop ebx
 	mov byte [exsdrawsprite], 1
 	mov byte [exscurfeature], 0
+	// EXP_ALTSPRITE
+	mov ebx, dword [mostrecentspritelist]
+	mov dword [exspritelst], ebx
+	pop ebx
 	ret
 
 global display2ndengine_noplayer
@@ -302,10 +345,15 @@
 
 	add ebx,[orgrvspritebase]
 	add ax,[ebx]
-
+	ret
 .gotit:
 	mov byte [exsdrawsprite], 1
 	mov byte [exscurfeature], 1
+	push ebx
+	// EXP_ALTSPRITE
+	mov ebx, dword [mostrecentspritelist]
+	mov dword [exspritelst], ebx
+	pop ebx
 	ret
 
 global displayrv_noplayer
@@ -322,10 +370,16 @@
 
 	add ebx,[orgplanespritebase]
 	add ax,[ebx]
-
+	
+	ret
 .gotit:
 	mov byte [exsdrawsprite], 1
 	mov byte [exscurfeature], 3
+	push ebx
+	// EXP_ALTSPRITE
+	mov ebx, dword [mostrecentspritelist]
+	mov dword [exspritelst], ebx
+	pop ebx
 	ret
 
 global displayplane_noplayer
@@ -366,8 +420,15 @@
 #ifndef NOVEHSPRITE
 	call getnewsprite
 	jc short .badsprite
+	
+	add bx,ax
 
-	add bx,ax
+	// EXP_ALTSPRITE
+	push edi
+	mov eax, [mostrecentspritelist]
+	mov edi, [esi+veh.veh2ptr]
+	mov [edi+veh2.spriteblockptr], eax
+	pop edi
 #else
 	mov bx,0
 	clc
@@ -464,6 +525,11 @@
 	sub dx,5
 	xchg edi,esi
 	xchg cl,[edi+veh.direction]
+	
+	// EXP_ALTSPRITE
+	mov ecx, dword [mostrecentspritelist]
+	mov dword [exspritelst], ecx
+	//
 	pop ecx
 
 	mov byte [exsdrawsprite], 1
@@ -480,8 +546,13 @@
 	xor esi,esi
 	mov eax,ebp
 	call getrotorsprite
+	// EXP_ALTSPRITE
+	mov esi, dword [mostrecentspritelist]
+	mov dword [exspritelst], esi
+	//
 	pop esi
 	sub dx,5
+	
 	mov byte [exsdrawsprite], 1
 	mov byte [exscurfeature], 3
 	ret
Index: procs/dogeneralpatching.asm
===================================================================
--- procs/dogeneralpatching.asm	(revision 2365)
+++ procs/dogeneralpatching.asm	(working copy)
@@ -1056,12 +1056,12 @@
 codefragment findremovespritefromcache,-2-4*WINTTDX
 	xchg esi,[spritedata+ecx*4]
 
-#if WINTTDX
 codefragment findspritecacheptr,12
 	lea ecx,[eax+5]
 	db 0x66,0x8e	// mov es,[...]
-#endif
 
+reusecodefragment findfetchspriteincache,findspritecacheptr,-18
+
 codefragment oldsavevehorders
 	mov ebp,[esi+veh.scheduleptr]
 	mov ax,[ebp]
@@ -2168,6 +2168,10 @@
 
 	patchcode oldsettracktypedefault,newsettracktypedefault,1,1
 	storeaddress findremovespritefromcache,1,1,removespritefromcache
+
+	extern fetchspriteincache
+	storeaddress findfetchspriteincache,1,1,fetchspriteincache
+
 #if WINTTDX
 	storeaddresspointer findspritecacheptr,1,1,spritecacheptr
 #endif
Index: procs/extendedspritelimit.asm
===================================================================
--- procs/extendedspritelimit.asm	(revision 2365)
+++ procs/extendedspritelimit.asm	(working copy)
@@ -1,5 +1,6 @@
 #include <defs.inc>
 #include <frag_mac.inc>
+#include <bitvars.inc>
 
 
 extern addgroundsprite,addgroundspritetodisplayspritenumber,addlinkedsprite
@@ -56,8 +57,10 @@
 
 codefragment newupdatevehiclespritebox
 	icall updatevehiclespritebox
+	
+codefragment newupdatevehiclespriteboxnew
+	ijmp UpdateVehicleSpriteboxNew
 
-
 codefragment oldsetmousecursor, 6
 	mov [curmousecursor], ebx
 	and ebx, 0x3FFF
@@ -75,18 +78,31 @@
 endcodefragments
 
 patchextendedspritelimit:
+#if 0
 	patchcode drawgroundspritesgetsprite
 	patchcode displayregularspritegetsprite
 	patchcode displayregularspriterelativegetsprite
 	patchcode displayregularspritelinkedgetsprite
-
+#endif
 	// feature specific patches
 	patchcode collectvehiclesprites
 
-	patchcode updatevehiclespritebox
+	stringaddress oldupdatevehiclespritebox
+	
+	push edi
+	storefragment newupdatevehiclespritebox
+	pop edi	
+	
+	test word [expswitches], EXP_ALTSPRITE
+	jz .noalternativespritesystem
+	storefragment newupdatevehiclespriteboxnew
+	
+.noalternativespritesystem:
+
 	patchcode setmousecursor
 	patchcode drawmousecursor
-
+	
+	
 	// Patch DrawSprite
 	mov edi, [drawspritefn]
 #if WINTTDX
Index: procs/spritesystem.asm
===================================================================
--- procs/spritesystem.asm	(revision 0)
+++ procs/spritesystem.asm	(revision 0)
@@ -0,0 +1,248 @@
+// TTDPatch sprite drawing, caching and loading system
+
+#include <defs.inc>
+#include <frag_mac.inc>
+#include <patchproc.inc>
+
+#include <player.inc>
+
+patchproc BIT(EXP_ALTSPRITE), patchspritesystem
+
+begincodefragments
+
+codefragment olddefragspritecache
+	mov word [spriterequestssincelasttick], 0
+	xor ebx, ebx
+
+codefragment newdefragspritecache
+	ret
+	
+codefragment oldfillrectanglegetsprite
+	mov bx, bp
+	and ebx, 0x3FFF
+
+codefragment newfillrectanglegetsprite
+	movzx ebx, bp
+	icall FetchSprite
+	setfragmentsize 74
+
+
+// different fragment as in extendedspritelimit, so both can happily work together
+codefragment oldsetmousecursor2, 25
+	cmp ebx, [curmousecursor]
+	jz near $+6+0xE1
+
+codefragment newsetmousecursor2
+	icall FetchSpriteMouseCursor
+	setfragmentsize 71
+
+codefragment oldsetmousecursor2ani, 1
+	push esi
+	and eax, 0x3FFF
+
+codefragment newsetmousecursor2ani
+	push ebx
+	mov ebx, eax
+	icall FetchSpriteMouseCursor
+	pop ebx
+	setfragmentsize 72
+	
+codefragment olddrawstringfetchsprite, 10 
+	and eax, 0xFF
+	mov ebx, 674
+
+codefragment newdrawstringfetchsprite 
+	icall FetchSprite
+	setfragmentsize 71
+
+codefragment olddrawstringfetchsprite2, 5
+	push esi
+	add bx, 2
+	// segment ss
+	
+codefragment newdrawstringfetchsprite2
+	icall FetchSpriteSS
+	setfragmentsize 71
+	
+codefragment olddrawmapownersmodefetchsprite, 9
+	movzx ebx, byte [edx+player.colourscheme]
+	add bx, 775
+	// segment ss
+	
+codefragment newdrawmapownersmodefetchsprite
+	icall FetchSprite
+	setfragmentsize 71
+	
+codefragment oldsetcharwidthtablesfetchsprite1, 10
+	// should use ss sometimes?
+	mov edi, charwidthtables
+	mov ebx, 2
+
+codefragment newsetcharwidthtablesfetchsprite1
+	icall FetchSprite
+	setfragmentsize 65
+	
+codefragment oldsetcharwidthtablesfetchsprite2, 6
+	jb short $+2-0x68
+	mov bx, 0xE2
+
+codefragment newsetcharwidthtablesfetchsprite2
+	icall FetchSprite
+	setfragmentsize 65
+
+codefragment oldsetcharwidthtablesfetchsprite3, 6
+	jb short $+2-0x6B
+	mov bx, 0x1C2
+	
+codefragment newsetcharwidthtablesfetchsprite3
+	icall FetchSprite
+	setfragmentsize 65
+
+codefragment oldinitwinsysfetchsprite, 10
+	mov ebp, colorschememap
+	mov ebx, 775
+	
+codefragment newinitwinsysfetchsprite
+	icall FetchSprite
+	setfragmentsize 65
+	
+codefragment oldshaperandlandfetchsprite,8
+	movzx ebx, ah
+	add bx, 4845
+
+codefragment newshaperandlandfetchsprite
+	icall FetchSprite
+	setfragmentsize 65
+
+codefragment oldallocspritecache2, -5
+	mov byte [usepredefinedmanagerfaces], 0
+
+codefragment newallocspritecache2
+	setfragmentsize 5
+	
+
+#if 0	
+codefragment oldinitspritesystem
+	cmp     bAdditionalSpriteFileNum, -1
+	
+	
+codefragment newinitspritesystem
+	setfragmentsize 1
+#endif
+
+
+codefragment finddrawlandscapelists,8
+	sub esp, 21000
+
+	
+codefragment findadditionalgrfnames, 8
+	or si, si
+	jz $+2+0x24
+		
+codefragment olddrawspritefunction
+	or bx, bx
+	jns $+6+0x165
+	mov ax, bx
+	shr ebx, 0x10
+
+codefragment newdrawspritefunction
+	ijmp DrawSpriteNew
+	setfragmentsize 9
+
+	
+codefragment oldinitializespritesystem, -7
+	jz $+2+0x0C
+	mov ebx, dword 1
+	mov al, 0
+
+codefragment newinitializespritesystem
+	ijmp InitializeSpriteSystem
+	setfragmentsize 7
+
+	
+codefragment_jmp newaddspritenew, AddSpriteNew, 10
+codefragment_jmp newaddlinkedspritenew, AddLinkedSpriteNew, 6
+codefragment_jmp newaddrelspritenew, AddRelSpriteNew, 6
+codefragment_jmp newaddgroundspritenew, AddGroundSpriteNew, 7
+
+
+endcodefragments
+	
+
+
+patchspritesystem:
+	patchcode defragspritecache
+	patchcode fillrectanglegetsprite
+
+	patchcode setmousecursor2
+	patchcode setmousecursor2ani
+	patchcode drawstringfetchsprite
+	patchcode drawstringfetchsprite2
+	patchcode drawmapownersmodefetchsprite
+	
+	extern getcharsprite, GetCharSpriteNew
+	mov dword [getcharsprite], GetCharSpriteNew
+	
+	
+	patchcode setcharwidthtablesfetchsprite1
+	patchcode setcharwidthtablesfetchsprite2
+	patchcode setcharwidthtablesfetchsprite3
+	
+	patchcode initwinsysfetchsprite
+	patchcode shaperandlandfetchsprite
+	
+	
+	// Kill the call to alloc the spritecache
+	// Note: in movespritecache the spritecache routines are changed too
+	// patchcode allocspritecache2
+	extern AllocateSpriteCacheNew
+	stringaddress oldallocspritecache2
+	storefunctioncall AllocateSpriteCacheNew
+	
+	patchcode initializespritesystem
+	
+	extern ttdgrfreplacementtables
+	
+	stringaddress findadditionalgrfnames
+	// mov eax, [edi]
+	// add eax, 4
+	
+	push esi
+	mov esi, [edi+7]
+	add esi, 4
+	mov edi, ttdgrfreplacementtables
+	movsd
+	movsd
+	movsd
+	pop esi
+	
+	stringaddress finddrawlandscapelists
+
+	extern paTempRegularSpriteList_ptr
+	extern reloc
+	
+	mov eax, [edi]
+	param_call reloc, eax, paTempRegularSpriteList_ptr
+
+	
+	// alter the sprite drawing routines
+	extern addsprite, AddSpriteNew
+	mov edi, [addsprite]
+	storefragment newaddspritenew
+
+	extern addlinkedsprite, AddLinkedSpriteNew
+	mov edi, [addlinkedsprite]
+	storefragment newaddlinkedspritenew
+
+
+	extern addrelsprite, AddRelSpriteNew
+	mov edi, [addrelsprite]
+	storefragment newaddrelspritenew
+
+	extern addgroundsprite, AddGroundSpriteNew
+	mov edi, [addgroundsprite]
+	storefragment newaddgroundspritenew
+
+	
+	patchcode drawspritefunction
+	ret

Property changes on: procs\spritesystem.asm
___________________________________________________________________
Added: svn:eol-style
   + native

Index: reloc.c
===================================================================
--- reloc.c	(revision 2365)
+++ reloc.c	(working copy)
@@ -20,3 +20,4 @@
 RELOC(vehtypedata)
 RELOC(objectpool)
 RELOC(window2ofs)
+RELOC(paTempRegularSpriteList)
