1 //**************************************************************************
3 //** ## ## ## ## ## #### #### ### ###
4 //** ## ## ## ## ## ## ## ## ## ## #### ####
5 //** ## ## ## ## ## ## ## ## ## ## ## ## ## ##
6 //** ## ## ######## ## ## ## ## ## ## ## ### ##
7 //** ### ## ## ### ## ## ## ## ## ##
8 //** # ## ## # #### #### ## ##
10 //** Copyright (C) 1999-2006 Jānis Legzdiņš
11 //** Copyright (C) 2018-2023 Ketmar Dark
13 //** This program is free software: you can redistribute it and/or modify
14 //** it under the terms of the GNU General Public License as published by
15 //** the Free Software Foundation, version 3 of the License ONLY.
17 //** This program is distributed in the hope that it will be useful,
18 //** but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 //** GNU General Public License for more details.
22 //** You should have received a copy of the GNU General Public License
23 //** along with this program. If not, see <http://www.gnu.org/licenses/>.
25 //**************************************************************************
26 #include "../gamedefs.h"
30 //==========================================================================
32 // VWarpTexture::VWarpTexture
34 //==========================================================================
35 VWarpTexture::VWarpTexture (VTexture
*ASrcTex
, float aspeed
)
47 Width
= SrcTex
->GetWidth();
48 Height
= SrcTex
->GetHeight();
49 SOffset
= SrcTex
->SOffset
;
50 TOffset
= SrcTex
->TOffset
;
51 SScale
= SrcTex
->SScale
;
52 TScale
= SrcTex
->TScale
;
54 if (Speed
< 1) Speed
= 1; else if (Speed
> 16) Speed
= 16;
55 mFormat
= mOrigFormat
= (SrcTex
? SrcTex
->Format
: TEXFMT_RGBA
);
59 //==========================================================================
61 // VWarpTexture::~VWarpTexture
63 //==========================================================================
64 VWarpTexture::~VWarpTexture () {
92 //==========================================================================
94 // VWarpTexture::IsDynamicTexture
96 //==========================================================================
97 bool VWarpTexture::IsDynamicTexture () const noexcept
{
102 //==========================================================================
104 // VWarpTexture::SetFrontSkyLayer
106 //==========================================================================
107 void VWarpTexture::SetFrontSkyLayer () {
108 SrcTex
->SetFrontSkyLayer();
112 //==========================================================================
114 // VWarpTexture::CheckModified
116 // returns 0 if not, positive if only data need to be updated, or
117 // negative to recreate texture
119 //==========================================================================
120 int VWarpTexture::CheckModified () {
121 return (GenTime
!= GTextureManager
.Time
*Speed
);
125 //==========================================================================
127 // VWarpTexture::GetPixels
129 //==========================================================================
130 vuint8
*VWarpTexture::GetPixels () {
131 if (Pixels
&& GenTime
== GTextureManager
.Time
*Speed
) return Pixels
;
133 const vuint8
*SrcPixels
= SrcTex
->GetPixels();
134 mFormat
= mOrigFormat
= SrcTex
->Format
;
135 transFlags
= SrcTex
->transFlags
;
137 GenTime
= GTextureManager
.Time
*Speed
;
138 Pixels8BitValid
= false;
139 Pixels8BitAValid
= false;
142 XSin1
= new float[Width
];
143 YSin1
= new float[Height
];
146 // precalculate sine values
147 for (int x
= 0; x
< Width
; ++x
) {
148 XSin1
[x
] = msin(GenTime
*44+x
/WarpXScale
*5.625f
+95.625f
)*8*WarpYScale
+8*WarpYScale
*Height
;
150 for (int y
= 0; y
< Height
; ++y
) {
151 YSin1
[y
] = msin(GenTime
*50+y
/WarpYScale
*5.625f
)*8*WarpXScale
+8*WarpXScale
*Width
;
154 if (mFormat
== TEXFMT_8
|| mFormat
== TEXFMT_8Pal
) {
155 if (!Pixels
) Pixels
= new vuint8
[Width
*Height
];
156 vuint8
*Dst
= Pixels
;
157 for (int y
= 0; y
< Height
; ++y
) {
158 for (int x
= 0; x
< Width
; ++x
) {
159 if (!(*Dst
++ = SrcPixels
[(((int)YSin1
[y
]+x
)%Width
)+(((int)XSin1
[x
]+y
)%Height
)*Width
])) transFlags
|= FlagTransparent
;
160 else transFlags
|= FlagHasSolidPixel
;
164 if (!Pixels
) Pixels
= new vuint8
[Width
*Height
*4];
165 vuint32
*Dst
= (vuint32
*)Pixels
;
166 for (int y
= 0; y
< Height
; ++y
) {
167 for (int x
= 0; x
< Width
; ++x
, ++Dst
) {
168 *Dst
= ((vuint32
*)SrcPixels
)[(((int)YSin1
[y
]+x
)%Width
)+(((int)XSin1
[x
]+y
)%Height
)*Width
];
169 const vuint8 a8
= (((*Dst
)>>24)&0xffu
);
170 if (a8
!= 0xffu
) transFlags
|= (a8
? FlagTranslucent
: FlagTransparent
);
171 else transFlags
|= FlagHasSolidPixel
;
180 //==========================================================================
182 // VWarpTexture::GetPalette
184 //==========================================================================
185 rgba_t
*VWarpTexture::GetPalette () {
186 return SrcTex
->GetPalette();
190 //==========================================================================
192 // VWarpTexture::GetHighResolutionTexture
194 //==========================================================================
195 VTexture
*VWarpTexture::GetHighResolutionTexture () {
196 //if (!r_hirestex) return nullptr;
197 // if high resolution texture is already created, then just return it
198 if (HiResTexture
) return HiResTexture
;
200 VTexture
*SrcTex
= VTexture::GetHighResolutionTexture();
201 if (!SrcTex
) return nullptr;
203 VWarpTexture
*NewTex
;
204 if (WarpType
== 1) NewTex
= new VWarpTexture(SrcTex
); else NewTex
= new VWarp2Texture(SrcTex
);
207 NewTex
->WarpXScale
= NewTex
->GetWidth()/GetWidth();
208 NewTex
->WarpYScale
= NewTex
->GetHeight()/GetHeight();
209 HiResTexture
= NewTex
;
214 //==========================================================================
216 // VWarp2Texture::VWarp2Texture
218 //==========================================================================
219 VWarp2Texture::VWarp2Texture (VTexture
*ASrcTex
, float aspeed
)
220 : VWarpTexture(ASrcTex
, aspeed
)
226 //==========================================================================
228 // VWarp2Texture::GetPixels
230 //==========================================================================
231 vuint8
*VWarp2Texture::GetPixels () {
232 if (Pixels
&& GenTime
== GTextureManager
.Time
*Speed
) return Pixels
;
233 Pixels8BitValid
= false;
234 Pixels8BitAValid
= false;
236 const vuint8
*SrcPixels
= SrcTex
->GetPixels();
237 mFormat
= mOrigFormat
= SrcTex
->Format
;
238 transFlags
= SrcTex
->transFlags
;
240 GenTime
= GTextureManager
.Time
*Speed
;
243 XSin1
= new float[Height
];
244 XSin2
= new float[Width
];
245 YSin1
= new float[Height
];
246 YSin2
= new float[Width
];
249 // precalculate sine values
250 for (int y
= 0; y
< Height
; ++y
) {
251 XSin1
[y
] = msin(y
/WarpYScale
*5.625f
+GenTime
*313.895f
+39.55f
)*2*WarpXScale
;
252 YSin1
[y
] = y
+(2*Height
+msin(y
/WarpYScale
*5.625f
+GenTime
*118.337f
+30.76f
)*2)*WarpYScale
;
254 for (int x
= 0; x
< Width
; ++x
) {
255 XSin2
[x
] = x
+(2*Width
+msin(x
/WarpXScale
*11.25f
+GenTime
*251.116f
+13.18f
)*2)*WarpXScale
;
256 YSin2
[x
] = msin(x
/WarpXScale
*11.25f
+GenTime
*251.116f
+52.73f
)*2*WarpYScale
;
259 if (mFormat
== TEXFMT_8
|| mFormat
== TEXFMT_8Pal
) {
260 if (!Pixels
) Pixels
= new vuint8
[Width
*Height
];
261 vuint8
*dest
= Pixels
;
262 for (int y
= 0; y
< Height
; ++y
) {
263 for (int x
= 0; x
< Width
; ++x
) {
264 *dest
++ = SrcPixels
[((int)(XSin1
[y
]+XSin2
[x
])%Width
)+((int)(YSin1
[y
]+YSin2
[x
])%Height
)*Width
];
268 if (!Pixels
) Pixels
= new vuint8
[Width
*Height
*4];
269 vuint32
*dest
= (vuint32
*)Pixels
;
270 for (int y
= 0; y
< Height
; ++y
) {
271 for (int x
= 0; x
< Width
; ++x
) {
272 int Idx
= ((int)(XSin1
[y
]+XSin2
[x
])%Width
)*4+((int)(YSin1
[y
]+YSin2
[x
])%Height
)*Width
*4;
273 *dest
++ = *(vuint32
*)(SrcPixels
+Idx
);
282 //==========================================================================
284 // VWarpTexture::ReleasePixels
286 //==========================================================================
287 void VWarpTexture::ReleasePixels () {
288 if (InReleasingPixels()) return; // already released
289 if (PixelsReleased()) return; // safeguard
290 VTexture::ReleasePixels();
291 ReleasePixelsLock
rlock(this);
292 if (SrcTex
) SrcTex
->ReleasePixels();