From b044a3a24f79d03d30f40939a29ed422bc65779c Mon Sep 17 00:00:00 2001 From: Flugente Date: Wed, 9 Aug 2017 20:28:56 +0000 Subject: [PATCH] Trade menu background is now generated with the use of random noise. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8444 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- Tactical/ShopKeeper Interface.cpp | 138 ++++++++++++++++++++++++++++-- 1 file changed, 129 insertions(+), 9 deletions(-) diff --git a/Tactical/ShopKeeper Interface.cpp b/Tactical/ShopKeeper Interface.cpp index 13f4322c..3da1eaaa 100644 --- a/Tactical/ShopKeeper Interface.cpp +++ b/Tactical/ShopKeeper Interface.cpp @@ -1305,6 +1305,59 @@ void HandleShopKeeperInterface() #endif } +// Flugente: for a fancy background we need a lot of random numbers +// Some of the following code was partially adapted from http://lodev.org/cgtutor/randomnoise.html +double noise[3000][3000]; + +// the background pixel colour values are stored in here. For simplicity we only generate them once +UINT16 backgroundval[3000][3000]; + +void generatenoise() +{ + for ( int y = 0; y < SKI_TOTAL_END_Y - SKI_TOTAL_BEGIN_Y; ++y ) + for ( int x = 0; x < SKI_TOTAL_END_X - SKI_TOTAL_BEGIN_X; ++x ) + { + noise[y][x] = (Random( 32768 ) % 32768) / 32768.0; + } +} + +double smoothNoise( double x, double y, int height, int width ) +{ + //get fractional part of x and y + double fractX = x - int( x ); + double fractY = y - int( y ); + + //wrap around + int x1 = (int( x ) + width) % width; + int y1 = (int( y ) + height) % height; + + //neighbor values + int x2 = (x1 + width - 1) % width; + int y2 = (y1 + height - 1) % height; + + //smooth the noise with bilinear interpolation + double value = 0.0; + value += fractX * fractY * noise[y1][x1]; + value += (1 - fractX) * fractY * noise[y1][x2]; + value += fractX * (1 - fractY) * noise[y2][x1]; + value += (1 - fractX) * (1 - fractY) * noise[y2][x2]; + + return value; +} + +double turbulence( double x, double y, int height, int width, double size ) +{ + double value = 0.0, initialSize = size; + + while ( size >= 1 ) + { + value += smoothNoise( x / size, y / size, height, width ) * size; + size /= 2.0; + } + + return(128.0 * value / initialSize); +} + BOOLEAN RenderShopKeeperInterface() { CHAR16 zMoney[128]; @@ -1335,18 +1388,85 @@ BOOLEAN RenderShopKeeperInterface() ColorFillVideoSurfaceArea( FRAME_BUFFER, SKI_TOTAL_BEGIN_X, SKI_TOTAL_BEGIN_Y, SKI_TOTAL_END_X, SKI_TOTAL_END_Y, col_tradescreenmargin ); + + // Flugente: because people find simple plane backgrounds to be offputting, we try for something more fancy + // generate noise once + static BOOLEAN noisegenerated = FALSE; - ColorFillVideoSurfaceArea( FRAME_BUFFER, SKI_TRADER_INVENTORY_BEGIN_X + SKI_MARGIN, SKI_TRADER_INVENTORY_BEGIN_Y + SKI_MARGIN, - SKI_TRADER_INVENTORY_END_X - SKI_MARGIN, SKI_TRADER_INVENTORY_END_Y - SKI_MARGIN, - col_tradescreen ); + if ( !noisegenerated ) + { + generatenoise(); - ColorFillVideoSurfaceArea( FRAME_BUFFER, SKI_TRADER_OFFER_BEGIN_X + SKI_MARGIN, SKI_TRADER_OFFER_BEGIN_Y + SKI_MARGIN, - SKI_TRADER_OFFER_END_X - SKI_MARGIN, SKI_TRADER_OFFER_END_Y - SKI_MARGIN, - col_tradescreen ); + noisegenerated = TRUE; - ColorFillVideoSurfaceArea( FRAME_BUFFER, SKI_PLAYER_OFFER_BEGIN_X + SKI_MARGIN, SKI_PLAYER_OFFER_BEGIN_Y + SKI_MARGIN, - SKI_PLAYER_OFFER_END_X - SKI_MARGIN, SKI_PLAYER_OFFER_END_Y - SKI_MARGIN, - col_tradescreen ); + int height = SKI_TOTAL_END_Y - SKI_TOTAL_BEGIN_Y; + int width = SKI_TOTAL_END_X - SKI_TOTAL_BEGIN_X; + double size = 64.0; + + //xPeriod and yPeriod together define the angle of the lines + //xPeriod and yPeriod both 0 ==> it becomes a normal clouds or turbulence pattern + double xPeriod = 2.0; //defines repetition of marble lines in x direction + double yPeriod = 4.0; //defines repetition of marble lines in y direction + //turbPower = 0 ==> it becomes a normal sine pattern + double turbPower = 3.0; //makes twists + double turbSize = 128.0; //initial size of the turbulence + + for ( int x = SKI_TOTAL_BEGIN_X; x < SKI_TOTAL_END_X; ++x ) + { + double xper = x * xPeriod / width; + + for ( int y = SKI_TRADER_INVENTORY_BEGIN_Y + SKI_MARGIN; y < SKI_TRADER_INVENTORY_END_Y - SKI_MARGIN; ++y ) + { + double xyValue = xper + y * yPeriod / height + turbPower * turbulence( x, y, height, width, turbSize ) / 256.0; + double sineValue = 100 * fabs( sin( xyValue * 3.14159 ) ); + UINT16 red = ( 30 + sineValue ); + UINT16 green = (10 + sineValue); + UINT16 blue = (sineValue); + + backgroundval[x][y] = Get16BPPColor( FROMRGB( red, green, blue ) ); + } + + for ( int y = SKI_TRADER_OFFER_BEGIN_Y + SKI_MARGIN; y < SKI_TRADER_OFFER_END_Y - SKI_MARGIN; ++y ) + { + double xyValue = xper + y * yPeriod / height + turbPower * turbulence( x, y, height, width, turbSize ) / 256.0; + double sineValue = 100 * fabs( sin( xyValue * 3.14159 ) ); + UINT16 red = (sineValue); + UINT16 green = (10 + sineValue); + UINT16 blue = (30 + sineValue); + + backgroundval[x][y] = Get16BPPColor( FROMRGB( red, green, blue ) ); + } + + for ( int y = SKI_PLAYER_OFFER_BEGIN_Y + SKI_MARGIN; y < SKI_PLAYER_OFFER_END_Y - SKI_MARGIN; ++y ) + { + double xyValue = xper + y * yPeriod / height + turbPower * turbulence( x, y, height, width, turbSize ) / 256.0; + double sineValue = 100 * fabs( sin( xyValue * 3.14159 ) ); + UINT16 red = (15 + sineValue); + UINT16 green = (30 + sineValue); + UINT16 blue = (15 + sineValue); + + backgroundval[x][y] = Get16BPPColor( FROMRGB( red, green, blue ) ); + } + } + } + + for ( int x = SKI_TOTAL_BEGIN_X; x < SKI_TOTAL_END_X; ++x ) + { + for ( int y = SKI_TRADER_INVENTORY_BEGIN_Y + SKI_MARGIN; y < SKI_TRADER_INVENTORY_END_Y - SKI_MARGIN; ++y ) + { + ColorFillVideoSurfaceArea( FRAME_BUFFER, x, y, x + 1, y + 1, backgroundval[x][y] ); + } + + for ( int y = SKI_TRADER_OFFER_BEGIN_Y + SKI_MARGIN; y < SKI_TRADER_OFFER_END_Y - SKI_MARGIN; ++y ) + { + ColorFillVideoSurfaceArea( FRAME_BUFFER, x, y, x + 1, y + 1, backgroundval[x][y] ); + } + + for ( int y = SKI_PLAYER_OFFER_BEGIN_Y + SKI_MARGIN; y < SKI_PLAYER_OFFER_END_Y - SKI_MARGIN; ++y ) + { + ColorFillVideoSurfaceArea( FRAME_BUFFER, x, y, x + 1, y + 1, backgroundval[x][y] ); + } + } { int usPosY = SKI_TRADER_INVENTORY_BOXES_BEGIN_Y;