Index: bitnames.ah
===================================================================
--- bitnames.ah	(revision 2330)
+++ 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 2330)
+++ globals.ah	(working copy)
@@ -342,6 +342,11 @@
 //	objects: newobjects
 ptrvar objectpool
 
+// Pointer to the regular sprite list sorting table
+// usage:
+//	newspritesystem
+ptrvar tempregularspritelist
+
 // Pointer to the temporary (not saved) vehicle data array
 uvard veh2ptr
 
Index: inc/spritedesc.inc
===================================================================
--- inc/spritedesc.inc	(revision 2330)
+++ 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:		resw 1	// 0x08
 	.unused:	resw 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 0)
+++ inc/spriteheader.inc	(revision 0)
@@ -0,0 +1,25 @@
+#include <var.inc>
+
+struc spriteheader
+	.flags:			resb 1
+#define SPRITE_TRANS 1		//	bit 0=Color index 0 is transparent. 
+#define SPRITE_LATEDECOMPRESS 2	//	bit 1=Sprite is decompressed when drawn
+#define SPRITE_CTILE 8		//	bit 2=Sprite is tile compressed
+#define SPRITE_SIZEREL 0x40	//	bit 6=The exact size of this sprite is significant
+#define SPRITE_PSEUDO 0xFF	//	bit *=Pseudo Sprite
+	.height:		resb 1
+	.width:			resw 1
+	.xoffset:		resw 1
+	.yoffset:		resw 1
+endstruc
+
+
+// note, this is accessed in reverse order, add new entries infront
+struc prespriteheader
+	// new entries here
+	.pseudoflag:		resb 1
+	.previousspriteptr:	resd 1
+	// don't touch the follwing entries:
+	.actionfeaturedata:	
+	.size:			resd 1
+endstruc
Index: inc/ttdvar.inc
===================================================================
--- inc/ttdvar.inc	(revision 2330)
+++ 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 2330)
+++ 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 2330)
+++ 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: patches/grfinit.asm
===================================================================
--- patches/grfinit.asm	(revision 2330)
+++ patches/grfinit.asm	(working copy)
@@ -381,9 +381,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
@@ -646,6 +653,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
Index: patches/grfload.asm
===================================================================
--- patches/grfload.asm	(revision 2330)
+++ patches/grfload.asm	(working copy)
@@ -1292,7 +1292,25 @@
 	test dword [miscmodsflags],MISCMODS_SMALLSPRITELIMIT
 	jz .exsenabled
 	jmp insertactivespriteblock
+
+.exsenablednew:
+	// 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-baseoursprites)
+	jnb short .toomany
+	add edi, ecx
+	// return spriteid as in the grf
+	ret
+
 .exsenabled:
+	test word [expswitches],EXP_ALTSPRITE
+	jnz .exsenablednew
+	
 	movzx eax, byte [exscurfeature]	// get the feature ID, stored before
 
 	push edi
@@ -1515,6 +1533,9 @@
 	ret
 
 .overwrite:
+	test word [expswitches],EXP_ALTSPRITE
+	jnz .overwritenew
+
 	cmp dword [ebx+edi*4],0	// is it currently in the cache?
 	je .notincache
 
@@ -1547,7 +1568,16 @@
 
 	add esi,ecx
 	ret
+	
+// FIXME: EXP_ALTSPRITE
+.overwritenew:
+	mov ebx,[newspritedata]
+	mov ebp,[newspritenum]
+	mov [ebx+edi*4], esi
+	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,1246 @@
+// 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>
+
+
+extern newspritedata
+extern exsfeaturespritetoreal
+
+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 tempregularspritelist
+ptrvarofs pTempRegularSpriteListEnd,tempregularspritelist,NREGULARSPRITESINLISTSIZE
+ptrvarofs pTempSpriteListEnd,tempregularspritelist,NREGULARSPRITESINLISTSIZE+4
+ptrvarofs pTempSpriteListHighMark,tempregularspritelist,NREGULARSPRITESINLISTSIZE+8
+ptrvarofs pTempFirstTextEffectDesc,tempregularspritelist,NREGULARSPRITESINLISTSIZE+12
+ptrvarofs pTempLastTextEffectDesc,tempregularspritelist,NREGULARSPRITESINLISTSIZE+16
+ptrvarofs pTempFirstGroundSpriteDesc,tempregularspritelist,NREGULARSPRITESINLISTSIZE+20
+ptrvarofs pTempLastGroundSpriteDesc,tempregularspritelist,NREGULARSPRITESINLISTSIZE+24
+ptrvarofs pTempLastSpriteInSubList,tempregularspritelist,NREGULARSPRITESINLISTSIZE+28	// used by Class 4 drawing too
+ptrvarofs wTempIsLastSpriteLinked,tempregularspritelist,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 totalsprites-103	// DOS: 4787 Win: 4793
+	dd 103
+	dd 172
+	dd 0
+	dd 0
+endvar
+
+uvard previoussprite
+
+
+uvard ttdgrfspritelst, 6
+uvard ttdgrfreplacementtables, 3
+
+
+exported AllocateSpriteCacheNew
+// We load all Sprites into memory
+	xor ecx, ecx
+.nextgrf:
+	pusha
+	mov eax, [ttdgrfsizes+ecx*4]
+	shl eax, 2
+	push ecx
+	call malloc
+	pop edi
+	
+
+	mov dword [ttdgrfspritelst+ecx*4], edi
+	mov edx, dword [ttdgrfnames+ecx*4]
+	mov ecx, dword [ttdgrfsizes+ecx*4]
+	call GRFLoader
+	popa
+	
+	inc ecx
+	cmp ecx, 6
+	jl .nextgrf
+	ret
+
+exported InitializeSpriteSystem
+	pusha
+	inc word [wgraphicssemaphore]
+	
+	call SpritesResetToDefault
+
+	dec word [wgraphicssemaphore]
+	popa
+	ret
+
+
+exported SpritesResetToDefault
+	extern numactsprites
+	mov dword [numactsprites],baseoursprites
+	extcall exsresetspritecounts
+	
+// Add Default TTD Sprites
+	mov esi, dword [ttdgrfspritelst]
+	mov edi, dword [newspritedata]
+	mov ecx, dword [ttdgrfsizes]
+	rep movsd
+// Add Intro
+	mov esi, dword [ttdgrfspritelst+4]
+	mov ecx, dword [ttdgrfsizes+4]
+	rep movsd
+
+	movzx eax, byte [climate]
+	or eax, eax
+	jz .done
+	
+// Load Climate depending sprites
+	mov esi, [ttdgrfspritelst+4+eax*4]
+	mov edi, [ttdgrfspritelst+4+eax*4]
+	mov edi, dword [newspritedata]
+	mov ebp, [ttdgrfreplacementtables-4+eax*4]
+	xor ebx, ebx
+.nextadditionalsprite:	
+	lodsd
+	mov bx, word [ebp]
+	mov [edi+ebx*4], eax
+
+	add ebp, 2
+	dec ecx
+	jnz .nextadditionalsprite
+.done:
+	ret
+
+
+// Load a TTD grf into memory (datasegment), 
+// edx = filename
+// edi = pointer to spritelist to use
+// ecx = spritelstmax
+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
+	
+	// edx = pointer to filename
+	
+	call GRFFileLoad
+	jc .fileopenfailed
+	
+	mov dword [previoussprite], 0
+.nextsprite:
+	mov esi, [%$numsprites]
+	cmp esi, [%$spritelstmax]
+	jae near .toomany
+	
+	push ebp
+	call GRFFileGetSprite
+	pop ebp
+	
+	test edx, edx
+	jz .closefile
+		
+	// edi = pointer to spritedata
+	// edx = sprite size
+	
+	inc dword [%$numsprites]
+	jmp .nextsprite
+
+.closefile:
+	call GRFFileClose
+
+
+	
+.createspritelst:
+// we now create the spritelist
+	mov ecx, dword [%$numsprites]
+	mov esi, ecx
+	
+	shl ecx, 2
+		
+	push ecx
+	call GRFAlloc
+	pop eax
+	jc .outofmem
+	
+	mov dword [%$spritelstpointer], eax
+	
+	
+.nextinspritelst:
+	mov [eax+esi*4],edi
+	mov edi, [edi-prespriteheader_size+prespriteheader.previousspriteptr]
+	dec esi
+	jnz .nextinspritelst
+
+.done:
+
+	
+	mov edi, [%$spritelstpointer]
+	_ret
+
+.fileopenfailed:
+	//TODO: add more usefull error message
+	mov edx, [%$filename]
+	extcall criticalerror
+	_ret
+	
+.outofmem:
+.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
+	mov edx, eax
+	test eax, eax
+	jz .nomoresprites
+	call GRFFileReadNextByte
+	
+	cmp al, 0xFF
+	jne .decompressgetsize
+
+.pseudo:
+	mov [esp+_pusha.edx], edx
+	mov ecx, edx
+	add ecx, prespriteheader_size
+	push ecx
+	call GRFAllocSprite
+	pop edi
+	jc .nomorememory
+	add edi, prespriteheader
+	
+	mov esi, [previoussprite]
+	mov dword [edi-prespriteheader_size+prespriteheader.previousspriteptr], esi
+	mov dword [edi-prespriteheader_size+prespriteheader.size], edx
+	mov dword [edi-prespriteheader_size+prespriteheader.pseudoflag], 0x59
+	mov [previoussprite], edi
+	mov [esp+_pusha.edi], edi
+	
+	or edi, edi
+	jz .failnomem
+	
+	mov ecx, edx
+	dec ecx
+	
+	mov [edi], al
+	inc edi
+	
+	// edi = pointer
+	// ecx = count
+	call GRFFileRead
+	jc .error
+	
+	popa
+	clc
+	ret
+	
+.nomoresprites:
+	mov dword [esp+_pusha.edi], 0
+	popa
+	clc
+	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
+	
+	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 dword [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
+
+	mov ecx, eax
+	sub edx, eax
+	call GRFFileRead
+	
+	jmp .nextchunk
+.earlierdata:
+	// earlier data
+	movzx ecx, al
+	sar cl, 3
+	neg cl
+	
+	// now cl = length
+	sub edx, ecx
+		
+	and al, 7
+	mov ah, al
+	call GRFFileReadNextByte
+
+	// now:	eax = offset
+	//	ecx = len
+	mov esi, edi
+	sub esi, eax
+	
+	rep movsb
+	jmp .nextchunk
+	
+.endofdata:
+	popa
+	clc
+	ret
+
+	
+GRFAlloc:
+	jmp malloc
+
+GRFAllocSprite:
+	jmp malloc
+	
+GRFReleaseSprite:
+	CALLINT3
+	ret
+	
+
+%define GRFFileReadBufferSize 0x4000
+uvarb GRFFileReadBuffer, GRFFileReadBufferSize
+uvard pGRFFileReadBuffer
+uvard GRFFileReadBufferLen
+
+
+// Load a GRF File
+// in:
+// edx = filenameptr
+// out:
+// carry flag set if error
+GRFFileLoad:
+	pusha
+	call dword [openfilefn]
+	jc .error
+	mov word [curfileblocksize], 0
+	mov word [tempspritefilehandle], bx
+	
+	call GRFFileRewind
+.error:
+	popa
+	ret
+
+	
+	
+GRFFileClose:
+	pusha
+	mov ax, 0x3e00
+	mov bx, [tempspritefilehandle]
+	CALLINT21
+	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
+	mov dword [GRFFileReadBufferLen], eax
+	
+	extern _md5_ctx_size
+	param_call _md5_ctx_size
+
+	popa
+	ret
+.error:
+	mov dword [GRFFileReadBufferLen], 0
+	popa
+	stc
+	ret
+	
+		
+// in:
+// ecx = count
+// edi = ptr to store data
+GRFFileRead:
+	pusha 
+	mov edx, ecx
+	
+	cmp dword [GRFFileReadBufferLen], 0
+	jz .bufferempty
+.next:
+	mov esi, dword [pGRFFileReadBuffer]
+	movsb
+	inc dword [pGRFFileReadBuffer]
+	dec dword [GRFFileReadBufferLen]
+	jz .bufferempty
+	dec ecx
+	jz .done
+	jmp .next
+	
+.bufferempty:
+	call GRFFileFillBuffer
+	jc .error
+	test eax, eax
+	jz .nomoredata
+	jmp .next
+.error:
+	stc
+.nomoredata:
+.done:
+	popa
+	ret
+
+// out:
+// al = read byte
+// carry = not possible
+GRFFileReadNextByte:
+	cmp dword [GRFFileReadBufferLen], 1
+	jz .bufferempty
+.readbyte:
+	push esi
+	mov esi, dword [pGRFFileReadBuffer]
+	lodsb
+	inc dword [pGRFFileReadBuffer]
+	dec dword [GRFFileReadBufferLen]
+	pop esi
+	clc
+	ret
+	
+.bufferempty:
+	call GRFFileFillBuffer
+	cmp word [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
+	add dword [pGRFFileReadBuffer], 2
+	sub dword [GRFFileReadBufferLen], 2
+	pop esi
+	clc
+	ret
+	
+.bufferempty:
+	call GRFFileFillBuffer
+	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
+	cmp word [GRFFileReadBufferLen], 0
+	je .fail
+.nextbyte:
+	mov esi, dword [pGRFFileReadBuffer]
+	mov ah, [esi]
+	inc dword [pGRFFileReadBuffer]
+	dec dword [GRFFileReadBufferLen]
+	pop esi
+	clc
+	ret	
+		
+
+GRFFileRewind:
+	pusha
+	or ecx, ecx
+	or 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)
+// uses: eax, ebx, esi, edi, ebp
+//
+
+exported DrawSpriteNew
+	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
+	
+	shl esi, 2
+	add esi, ebp	// newspritedata
+	mov esi, [esi]
+	
+	mov es, [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
+	jmp [drawspriteonscreen]
+	
+	
+
+	
+// 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
+	extcall setmousecursorsprite
+	
+	mov esi, ebx
+	shl esi, 2
+	add esi, [newspritedata]
+	mov esi, [esi]
+	ret
+
+
+// ----------------------- Add*Sprite --------------------
+#if 1
+uvard exspritelst
+
+#else
+extern exsspritelistext, exscurfeature
+#endif
+
+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]
+	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]
+	
+	// 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
+	
+	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
+	
+	// are these coordinates outside?
+	cmp ax, [esi+scrnblockdesc.x]
+	jle near .outside
+	cmp cx, [esi+scrnblockdesc.y]
+	jle near .outside
+	
+	mov [ebp+spritedesc.pixelX2], ax
+	mov [ebp+spritedesc.pixelY2], cx
+	
+	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]
+	mov esi, [esi]
+	
+	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, [esi+scrnblockdesc.x]
+	jle near .outside
+	cmp cx, [esi+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...
+	mov [pTempLastSpriteInSubList], ebp
+	add dword [pTempSpriteListEnd], linkedspritedesc_size
+	xor edx, edx
+	
+	mov edi, 1
+	xchg di, [wTempIsLastSpriteLinked]
+	or edi, edi
+	jnz .lastwaslinked
+	mov [ebx+spritedesc.linked], ebp
+	or word [ebx+spritedesc.flags], 0x80
+	ret
+.lastwaslinked:
+	mov [ebx+linkedspritedesc.next], ebp
+	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...
+	mov [pTempLastSpriteInSubList], ebp
+	add dword [pTempSpriteListEnd], relspritedesc_size
+	
+	mov [ebp+relspritedesc.xoffset], ax
+	mov [ebp+relspritedesc.yoffset], cx
+	mov dword [ebp+relspritedesc.next], 0
+	xor edx, edx
+	
+	mov edi, 1
+	xchg di, [wTempIsLastSpriteLinked]
+	or edi, edi
+	jnz .lastwasrelative
+	mov [ebx+spritedesc.linked], ebp
+	ret
+.lastwasrelative:
+	mov [ebx+relspritedesc.next], ebp	
+	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
+	
+#if 0
+exported DrawRegularSpritesNew
+	mov esi, tempregularspritelist
+.nextsprite:
+	mov ebp, [esi]
+	or ebp, ebp
+	jz near .done
+
+	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
+	
+	mov esi, [ebp+spritedesc.linked]
+	or esi, esi
+	jnz .relorlinkesprite
+.getnextsprite:
+	pop esi
+	add esi, 4
+	jmp .nextsprite
+	
+.relorlinkesprite:
+	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
+#endif
+	
+// ----------------------- Vehicle Code --------------------
+UpdateVehicleSpritebox:
+	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
+	shl ebp, 2
+	add ebp, ecx
+.nogrfspecificspriteblock:
+	movzx ebp, word [esi+veh.cursprite]
+	
+	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:
+#if 0
+	mov al, [esi+veh.class]	
+	sub al, 0x10
+	cmp al, 3
+	ja .special
+	mov [exscurfeature], bl
+	xchg ebx, ebp
+	call exsfeaturespritetoreal
+	xchg ebx, ebp
+.special:
+	shl ebp, 2
+	add ebp, [newspritedata]
+#endif	
+
+	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]
+	xor dh, dh
+	
+	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/newsprit.asm
===================================================================
--- patches/newsprit.asm	(revision 2330)
+++ patches/newsprit.asm	(working copy)
@@ -15,6 +15,7 @@
 #include <transopts.inc>
 #include <idf.inc>
 #include <objects.inc>
+#include <bitvars.inc>
 
 extern acttriggers,cachevehvar40x,canalfeatureids,cargoaction3,curcallback
 extern curgrffile,curgrfsprite,curstationtile,curtriggers,ecxcargooffset
@@ -47,6 +48,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,11 +653,15 @@
 		// 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
-
-		// also record the spriteblock for code following the getnewsprite call
+	
+	// also record the spriteblock for code following the getnewsprite call
 	mov [mostrecentspriteblock],edx
 
 	cmp byte [curcallback],2
Index: patches/sprite.asm
===================================================================

Property changes on: patches\sprite.asm
___________________________________________________________________
Added: svn:eol-style
   + native

Index: patches/vehspri.asm
===================================================================
--- patches/vehspri.asm	(revision 2330)
+++ patches/vehspri.asm	(working copy)
@@ -17,6 +17,7 @@
 #include <player.inc>
 #include <window.inc>
 #include <industry.inc>		// For indu var 45
+#include <bitvars.inc>
 
 extern cargoamountnnamesptr,cargoclass,curgrfid
 extern cargotypes,deftwocolormaps,exscurfeature
@@ -366,8 +367,17 @@
 #ifndef NOVEHSPRITE
 	call getnewsprite
 	jc short .badsprite
+	
+	add bx,ax
 
-	add bx,ax
+	extern expswitches
+	test word [expswitches],EXP_ALTSPRITE
+	jz .altspritedisabled
+	push edi
+//	mov eax, [mostrecentspritelist]
+	mov edi, [esi+veh.veh2ptr]
+.altspritedisabled:
+	pop edi
 #else
 	mov bx,0
 	clc
Index: procs/dogeneralpatching.asm
===================================================================
--- procs/dogeneralpatching.asm	(revision 2330)
+++ 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/spritesystem.asm
===================================================================
--- procs/spritesystem.asm	(revision 0)
+++ procs/spritesystem.asm	(revision 0)
@@ -0,0 +1,215 @@
+// 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, 19
+	cmp ebx, [curmousecursor]
+	jz near $+6+0xE1
+
+codefragment newsetmousecursor2
+	icall FetchSpriteMouseCursor
+	setfragmentsize 77
+
+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 $+2+0x98
+	mov bx, 0xE2
+
+codefragment newsetcharwidthtablesfetchsprite2
+	icall FetchSprite
+	setfragmentsize 65
+
+codefragment oldsetcharwidthtablesfetchsprite3, 6
+	jb $+2+0x95
+	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,5
+	mov esi, esp
+	sub esi, 0x40
+
+	
+codefragment findadditionalgrfnames,-30-2*WINTTDX
+	mov esi, esp
+	sub esi, 0x40	
+	
+endcodefragments
+	
+
+
+patchspritesystem:
+	patchcode defragspritecache
+	patchcode fillrectanglegetsprite
+	patchcode setmousecursor2
+	patchcode setmousecursor2ani
+	patchcode drawstringfetchsprite
+	patchcode drawstringfetchsprite2
+	patchcode drawmapownersmodefetchsprite
+	
+	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
+	
+	extern ttdgrfreplacementtables
+	stringaddress findadditionalgrfnames
+	
+	sub edi, 12
+	mov eax, [edi]
+	mov [ttdgrfreplacementtables], eax
+	mov eax, [edi+4]
+	mov [ttdgrfreplacementtables+4], eax
+	mov eax, [edi+8]
+	mov [ttdgrfreplacementtables+8], eax
+	
+	stringaddress finddrawlandscapelists
+	
+	extern tempregularspritelist_ptr
+	extern reloc
+	
+	lea eax, [edi+18]
+	param_call reloc, eax, tempregularspritelist_ptr
+	
+	// alter the sprite drawing routines
+	extern addsprite, AddSpriteNew
+	mov edi, [addsprite]
+	storefunctioncall AddSpriteNew
+	mov byte [edi+6], 0x90
+	mov dword [addsprite], AddSpriteNew
+	
+
+	extern addlinkedsprite, AddLinkedSpriteNew
+	mov edi, [addlinkedsprite]
+	storefunctioncall AddLinkedSpriteNew
+	mov byte [edi+6], 0x90
+	mov dword [addlinkedsprite], AddLinkedSpriteNew
+
+	extern addrelsprite, AddRelSpriteNew
+	mov edi, [addrelsprite]
+	storefunctioncall AddRelSpriteNew
+	mov byte [edi+6], 0x90
+	mov dword [addrelsprite], AddRelSpriteNew
+	
+	extern addgroundsprite, AddGroundSpriteNew
+	mov edi, [addgroundsprite]
+	storefunctioncall AddGroundSpriteNew
+	mov byte [edi+6], 0x90
+	mov dword [addgroundsprite], AddGroundSpriteNew
+	
+	ret

Property changes on: procs\spritesystem.asm
___________________________________________________________________
Added: svn:eol-style
   + native

Index: reloc.c
===================================================================
--- reloc.c	(revision 2330)
+++ reloc.c	(working copy)
@@ -20,3 +20,4 @@
 RELOC(vehtypedata)
 RELOC(objectpool)
 RELOC(window2ofs)
+RELOC(tempregularspritelist)
