rubysketch-solitaire 0.1.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +3 -0
  3. data/.gitignore +2 -0
  4. data/.hooks/pre-commit +69 -0
  5. data/ChangeLog.md +21 -0
  6. data/Gemfile.lock +10 -10
  7. data/Podfile.lock +33 -33
  8. data/Rakefile +107 -10
  9. data/RubySolitaire/Ad.swift +88 -0
  10. data/RubySolitaire/Assets.xcassets/AppIcon.appiconset/AppIcon.png +0 -0
  11. data/RubySolitaire/Assets.xcassets/AppIcon.appiconset/Contents.json +3 -87
  12. data/RubySolitaire/Base.lproj/Localizable.strings +6 -0
  13. data/RubySolitaire/Extensions.swift +5 -0
  14. data/RubySolitaire/GameView.swift +75 -13
  15. data/RubySolitaire/Helper.swift +70 -0
  16. data/RubySolitaire/MenuScreen.swift +140 -0
  17. data/RubySolitaire/RubySolitaireApp.swift +188 -1
  18. data/RubySolitaire/SafariView.swift +16 -0
  19. data/RubySolitaire/Strings.swift +48 -0
  20. data/RubySolitaire/ja.lproj/InfoPlist.strings +4 -0
  21. data/RubySolitaire/ja.lproj/Localizable.strings +6 -0
  22. data/VERSION +1 -1
  23. data/data/card.png +0 -0
  24. data/data/classicPSPWave.glsl +94 -0
  25. data/data/colorfulUnderwaterBubbles2.glsl +113 -0
  26. data/data/cosmic2.glsl +121 -0
  27. data/data/reflectiveHexes.glsl +219 -0
  28. data/fastlane/Fastfile +76 -0
  29. data/fastlane/metadata/copyright.txt +1 -0
  30. data/fastlane/metadata/en-US/apple_tv_privacy_policy.txt +1 -0
  31. data/fastlane/metadata/en-US/description.txt +5 -0
  32. data/fastlane/metadata/en-US/keywords.txt +1 -0
  33. data/fastlane/metadata/en-US/marketing_url.txt +1 -0
  34. data/fastlane/metadata/en-US/name.txt +1 -0
  35. data/fastlane/metadata/en-US/privacy_url.txt +1 -0
  36. data/fastlane/metadata/en-US/promotional_text.txt +1 -0
  37. data/fastlane/metadata/en-US/release_notes.txt +1 -0
  38. data/fastlane/metadata/en-US/subtitle.txt +1 -0
  39. data/fastlane/metadata/en-US/support_url.txt +1 -0
  40. data/fastlane/metadata/ja/apple_tv_privacy_policy.txt +1 -0
  41. data/fastlane/metadata/ja/description.txt +5 -0
  42. data/fastlane/metadata/ja/keywords.txt +1 -0
  43. data/fastlane/metadata/ja/marketing_url.txt +1 -0
  44. data/fastlane/metadata/ja/name.txt +1 -0
  45. data/fastlane/metadata/ja/privacy_url.txt +1 -0
  46. data/fastlane/metadata/ja/promotional_text.txt +1 -0
  47. data/fastlane/metadata/ja/release_notes.txt +1 -0
  48. data/fastlane/metadata/ja/subtitle.txt +1 -0
  49. data/fastlane/metadata/ja/support_url.txt +1 -0
  50. data/fastlane/metadata/primary_category.txt +1 -0
  51. data/fastlane/metadata/primary_first_sub_category.txt +1 -0
  52. data/fastlane/metadata/primary_second_sub_category.txt +1 -0
  53. data/fastlane/metadata/review_information/demo_password.txt +1 -0
  54. data/fastlane/metadata/review_information/demo_user.txt +1 -0
  55. data/fastlane/metadata/review_information/email_address.txt +1 -0
  56. data/fastlane/metadata/review_information/first_name.txt +0 -0
  57. data/fastlane/metadata/review_information/last_name.txt +0 -0
  58. data/fastlane/metadata/review_information/notes.txt +1 -0
  59. data/fastlane/metadata/review_information/phone_number.txt +0 -0
  60. data/fastlane/metadata/secondary_category.txt +1 -0
  61. data/fastlane/metadata/secondary_first_sub_category.txt +1 -0
  62. data/fastlane/metadata/secondary_second_sub_category.txt +1 -0
  63. data/lib/rubysketch/solitaire/background.rb +115 -12
  64. data/lib/rubysketch/solitaire/card.rb +10 -87
  65. data/lib/rubysketch/solitaire/common/animation.rb +34 -34
  66. data/lib/rubysketch/solitaire/common/button.rb +49 -19
  67. data/lib/rubysketch/solitaire/common/dialog.rb +78 -21
  68. data/lib/rubysketch/solitaire/common/scene.rb +15 -4
  69. data/lib/rubysketch/solitaire/common/settings.rb +10 -2
  70. data/lib/rubysketch/solitaire/common/timer.rb +2 -2
  71. data/lib/rubysketch/solitaire/common/transitions.rb +12 -6
  72. data/lib/rubysketch/solitaire/common/utils.rb +15 -0
  73. data/lib/rubysketch/solitaire/klondike.rb +378 -81
  74. data/lib/rubysketch/solitaire/places.rb +12 -102
  75. data/lib/rubysketch/solitaire/skin.rb +151 -0
  76. data/lib/rubysketch/solitaire.rb +33 -9
  77. data/main.rb +1 -0
  78. data/project.yml +85 -4
  79. metadata +54 -2
@@ -0,0 +1,94 @@
1
+ // PSP Classic Wave by ParkingLotGames (github/ParkingLotGames)
2
+ // https://www.shadertoy.com/view/ddV3DK
3
+ // Original for Unity: https://github.com/ParkingLotGames/PSP-Classic-Wave-Unity-Shader
4
+ // License: MIT
5
+
6
+ /*
7
+ MIT License
8
+
9
+ Copyright (c) 2023 Parking Lot Studio
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in all
19
+ copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ SOFTWARE.
28
+ */
29
+
30
+ void mainImage( out vec4 fragColor, in vec2 fragCoord )
31
+ {
32
+ vec4 _TopColor = vec4(0.04, 0.19, 0.54, 1.0);
33
+ vec4 _BottomColor = vec4(0.04, 0.69, 0.87, 1.0);
34
+
35
+ vec2 uv = fragCoord/iResolution.xy;
36
+
37
+ float _Frequency = 4.29;
38
+ float _OuterWavesAmplitude = 0.5;
39
+ float _InnerWavesAmplitude = 0.18;
40
+ float _OuterWavesSpeed = 0.044;
41
+ float _InnerWavesSpeed = 0.064;
42
+ float _OuterWave1Falloff = 2.0;
43
+ float _OuterWave2Falloff = 2.0;
44
+ float _InnerWave1Falloff = 1.0;
45
+ float _InnerWave2Falloff = 1.0;
46
+
47
+ vec3 white = vec3(1.0, 1.0, 1.0);
48
+
49
+ float topOuterWave = sin((uv.x + (iTime * (_OuterWavesSpeed + (0.0025 * 1.0)))) * _Frequency) * _OuterWavesAmplitude;
50
+ float bottomOuterWave = sin((uv.x + (iTime * (_OuterWavesSpeed + (0.0025 * 20.0)))) * _Frequency) * _OuterWavesAmplitude;
51
+ float topInnerWave = sin((uv.x + (iTime * (_InnerWavesSpeed + (0.0025 * 8.0)))) * _Frequency) * _InnerWavesAmplitude;
52
+ float bottomInnerWave = sin((uv.x + (iTime * (_InnerWavesSpeed + (0.0025 * 40.0)))) * _Frequency) * _InnerWavesAmplitude;
53
+
54
+ float topOuterWaveFalloff = topOuterWave;
55
+ float bottomOuterWaveFalloff = bottomOuterWave;
56
+ float topInnerWaveFalloff = topInnerWave;
57
+ float bottomInnerWaveFalloff = bottomInnerWave;
58
+
59
+ topOuterWave += 1.0 - (1.0 - uv.y) * 6.0;
60
+ bottomOuterWave += 1.0 - (uv.y * 6.0);
61
+ topInnerWave += 1.0 - (uv.y) * 2.5;
62
+ bottomInnerWave += 1.0 - (1.0 - uv.y) * 2.5;
63
+
64
+ topOuterWaveFalloff += 1.0 - (1.0 - uv.y - 0.2) * 6.0;
65
+ bottomOuterWaveFalloff += 1.0 - ((uv.y - 0.2) * 6.0);
66
+ topInnerWaveFalloff += 1.0 - ((uv.y - 0.1) * 2.2);
67
+ bottomInnerWaveFalloff += 1.0 - (((1.0 - uv.y - 0.1)) * 2.2);
68
+
69
+ float wave1 = 1.0 - smoothstep(0.0, 0.025, topOuterWave);
70
+ float wave2 = 1.0 - smoothstep(0.0, 0.025, bottomOuterWave);
71
+ float wave3 = 1.0 - smoothstep(0.0, 0.025, topInnerWave);
72
+ float wave4 = 1.0 - smoothstep(0.0, 0.025, bottomInnerWave);
73
+
74
+ float wave1Falloff = 1.0 - smoothstep(0.0, _OuterWave1Falloff, topOuterWaveFalloff);
75
+ float wave2Falloff = 1.0 - smoothstep(0.0, _OuterWave2Falloff, bottomOuterWaveFalloff);
76
+ float wave3Falloff = 1.0 - smoothstep(0.0, _InnerWave1Falloff, topInnerWaveFalloff);
77
+ float wave4Falloff = 1.0 - smoothstep(0.0, _InnerWave2Falloff, bottomInnerWaveFalloff);
78
+
79
+ wave1 -= wave1Falloff;
80
+ wave2 -= wave2Falloff;
81
+ wave3 -= wave3Falloff;
82
+ wave4 -= wave4Falloff;
83
+
84
+ wave1 = clamp(wave1, 0.0, 1.0);
85
+ wave2 = clamp(wave2, 0.0, 1.0);
86
+ wave3 = clamp(wave3, 0.0, 1.0);
87
+ wave4 = clamp(wave4, 0.0, 1.0);
88
+
89
+ float wave = wave1 + wave2 + wave3 + wave4;
90
+ vec4 waveContribution = vec4(white,wave);
91
+ vec4 background = vec4(mix(_BottomColor.rgb, _TopColor.rgb, uv.y), 1.0);
92
+
93
+ fragColor = mix(background, waveContribution, wave);
94
+ }
@@ -0,0 +1,113 @@
1
+ // CCO: Colorful underwater bubbles II
2
+ // Recoloring of earlier shader + spherical shading
3
+
4
+ #define const
5
+
6
+ #define TIME iTime
7
+ #define RESOLUTION iResolution
8
+ #define PI 3.141592654
9
+ #define TAU (2.0*PI)
10
+ const float MaxIter = 12.0;
11
+
12
+ // License: Unknown, author: Unknown, found: don't remember
13
+ float hash(float co) {
14
+ return fract(sin(co*12.9898) * 13758.5453);
15
+ }
16
+
17
+ // License: Unknown, author: Unknown, found: don't remember
18
+ float hash(vec2 co) {
19
+ return fract(sin(dot(co.xy ,vec2(12.9898,58.233))) * 13758.5453);
20
+ }
21
+
22
+ // License: MIT OR CC-BY-NC-4.0, author: mercury, found: https://mercury.sexy/hg_sdf/
23
+ vec2 mod2(inout vec2 p, vec2 size) {
24
+ vec2 c = floor((p + size*0.5)/size);
25
+ p = mod(p + size*0.5,size) - size*0.5;
26
+ return c;
27
+ }
28
+
29
+ vec4 plane(vec2 p, float i, float zf, float z, vec3 bgcol) {
30
+ float sz = 0.5*zf;
31
+ vec2 cp = p;
32
+ vec2 cn = mod2(cp, vec2(2.0*sz, sz));
33
+ float h0 = hash(cn+i+123.4);
34
+ float h1 = fract(4483.0*h0);
35
+ float h2 = fract(8677.0*h0);
36
+ float h3 = fract(9677.0*h0);
37
+ float h4 = fract(7877.0*h0);
38
+ float h5 = fract(9967.0*h0);
39
+ if (h4 < 0.5) {
40
+ return vec4(0.0);
41
+ }
42
+ float fi = exp(-0.25*max(z-2.0, 0.0));
43
+ float aa = mix(0.0125, 2.0/RESOLUTION.y, fi);
44
+ float r = sz*mix(0.1, 0.475, h0*h0);
45
+ float amp = mix(0.5, 0.5, h3)*r;
46
+ cp.x -= amp*sin(mix(3.0, 0.25, h0)*TIME+TAU*h2);
47
+ cp.x += 0.95*(sz-r-amp)*sign(h3-0.5)*h3;
48
+ cp.y += 0.475*(sz-2.0*r)*sign(h5-0.5)*h5;
49
+ float d = length(cp)-r;
50
+ if (d > aa) {
51
+ return vec4(0.0);
52
+ }
53
+ vec3 ocol = (0.5+0.5*sin(vec3(0.0, 1.0, 2.0)+h1*TAU));
54
+ vec3 icol = sqrt(ocol);
55
+ ocol *= 1.5;
56
+ icol *= 2.0;
57
+ const vec3 lightDir = normalize(vec3(1.0, 1.5, 2.0));
58
+ float z2 = (r*r-dot(cp, cp));
59
+ vec3 col = ocol;
60
+ float t = smoothstep(aa, -aa, d);
61
+ if (z2 > 0.0) {
62
+ float z = sqrt(z2);
63
+ t *= mix(1.0, 0.8, z/r);
64
+ vec3 pp = vec3(cp, z);
65
+ vec3 nn = normalize(pp);
66
+ float dd= max(dot(lightDir, nn), 0.0);
67
+
68
+ col = mix(ocol, icol, dd*dd*dd);
69
+ }
70
+ col *= mix(0.8, 1.0, h0);
71
+ col = mix(bgcol, col, fi);
72
+ return vec4(col, t);
73
+ }
74
+
75
+ // License: Unknown, author: Claude Brezinski, found: https://mathr.co.uk/blog/2017-09-06_approximating_hyperbolic_tangent.html
76
+ float tanh_approx(float x) {
77
+ // Found this somewhere on the interwebs
78
+ // return tanh(x);
79
+ float x2 = x*x;
80
+ return clamp(x*(27.0 + x2)/(27.0+9.0*x2), -1.0, 1.0);
81
+ }
82
+
83
+ vec3 effect(vec2 p, vec2 pp) {
84
+ const vec3 bgcol0 = vec3(0.1, 0.0, 1.0)*0.1;
85
+ const vec3 bgcol1 = vec3(0.0, 0.4, 1.0)*0.6;
86
+ vec3 bgcol = mix(bgcol1, bgcol0, tanh_approx(1.5*length(p)));
87
+ vec3 col = bgcol;
88
+
89
+ for (float i = 0.0; i < MaxIter; ++i) {
90
+ const float Near = 4.0;
91
+ float z = MaxIter - i;
92
+ float zf = Near/(Near + MaxIter - i);
93
+ vec2 sp = p;
94
+ float h = hash(i+1234.5);
95
+ sp.y += -mix(0.2, 0.3, h*h)*TIME*zf;
96
+ sp += h;
97
+ vec4 pcol = plane(sp, i, zf, z, bgcol);
98
+ col = mix(col, pcol.xyz, pcol.w);
99
+ }
100
+ col *= smoothstep(1.5, 0.5, length(pp));
101
+ col = clamp(col, 0.0, 1.0);
102
+ col = sqrt(col);
103
+ return col;
104
+ }
105
+
106
+ void mainImage(out vec4 fragColor, in vec2 fragCoord) {
107
+ vec2 q = fragCoord/RESOLUTION.xy;
108
+ vec2 p = -1. + 2. * q;
109
+ vec2 pp = p;
110
+ p.x *= RESOLUTION.x/RESOLUTION.y;
111
+ vec3 col = effect(p, pp);
112
+ fragColor = vec4(col, 1.0);
113
+ }
data/data/cosmic2.glsl ADDED
@@ -0,0 +1,121 @@
1
+ // Started as Star Nest by Pablo Román Andrioli
2
+ // Modifications by Beibei Wang and Huw Bowles.
3
+ // This content is under the MIT License.
4
+
5
+ // On reducing the spatial high frequency noise:
6
+
7
+ // We simply limit the size of each contribution of each iteration of the fractal using min():
8
+ // a += i > 7 ? min( 12.,abs(length(p)-pa)) : abs(length(p)-pa)
9
+ // The test on the iteration count is optional, we found that most of the problem noise is introduced in the later
10
+ // iterations so we found that keeping the original formula for the earlier iterations helps to retain the 'volume'
11
+ // without the noise.
12
+
13
+
14
+ // On reducing the temporal noise:
15
+
16
+ // This version has volume samples aligned along view space Z isolines. When the camera moves
17
+ // forwards, the samples are shifted towards the viewer, allowing the camera to move forward
18
+ // smoothly without aliasing (besides the high frequency speckle noise).
19
+
20
+ // However if the camera were to rotate around its origin, the volume samples towards
21
+ // the sides of the image sweep in Z and aliasing would occur. To make this case work, the samples
22
+ // need to be arranged in concentric rings around the camera. However in this configuration
23
+ // there will be some aliasing at the sides of the screen when the camera moves forward,
24
+ // because the motion of the camera can no longer be compensated for completely - one can
25
+ // pull in the vert rings but they will move at different rates in Z
26
+
27
+ // I had similar issues in a different context and made some diagrams etc, see
28
+ // http://advances.realtimerendering.com/s2013/OceanShoestring_SIGGRAPH2013_Online.pptx
29
+ // And developed a fast realtime version of adaptive stationary sampling:
30
+ // https://www.shadertoy.com/view/XdBXWW
31
+
32
+
33
+ // Question - the derivative can be computed for "free" using dual numbers, as in https://www.shadertoy.com/view/Xd2GzR .
34
+ // The derivate may help to eliminate noise? Or perhaps the second derivate. It would be very interesting to see these
35
+ // derivatives rendered.
36
+
37
+ #define iterations 17
38
+ #define formuparam 0.53
39
+
40
+ #define volsteps 18
41
+ #define stepsize 0.050
42
+
43
+ #define zoom 0.800
44
+ #define tile 0.850
45
+ #define speed 0.10
46
+
47
+ #define brightness 0.0015
48
+ #define darkmatter 0.300
49
+ #define distfading 0.760
50
+ #define saturation 0.800
51
+
52
+
53
+ void mainImage( out vec4 fragColor, in vec2 fragCoord )
54
+ {
55
+ //get coords and direction
56
+ vec2 uv=fragCoord.xy/iResolution.xy-.5;
57
+ uv.y*=iResolution.y/iResolution.x;
58
+ vec3 dir=vec3(uv*zoom,1.);
59
+ float time=(iTime-3311.)*speed;
60
+
61
+
62
+ vec3 from=vec3(1.,.5,0.5);
63
+
64
+
65
+ vec3 forward = vec3(0.,0.,1.);
66
+
67
+ //mouse rotation
68
+ float a1 = 0.3;//3.1415926 * (iMouse.x/iResolution.x-.5);
69
+ mat2 rot1 = mat2(cos(a1),sin(a1),-sin(a1),cos(a1));
70
+ float a2 = .6;//3.1415926 * (iMouse.y/iResolution.y-.5);
71
+ mat2 rot2 = mat2(cos(a2),sin(a2),-sin(a2),cos(a2));
72
+ dir.xz*=rot1;
73
+ forward.xz *= rot1;
74
+ dir.yz*=rot1;
75
+ forward.yz *= rot1;
76
+
77
+ // pan (dodgy)
78
+ from += (iMouse.x/iResolution.x-.5)*vec3(-forward.z,0.,forward.x);
79
+
80
+ //zoom
81
+ float zooom = time;
82
+ from += forward* zooom;
83
+ float sampleShift = mod( zooom, stepsize );
84
+ float zoffset = -sampleShift;
85
+ sampleShift /= stepsize; // make from 0 to 1
86
+
87
+ //volumetric rendering
88
+ float s=0.1;
89
+ vec3 v=vec3(0.);
90
+ for (int r=0; r<volsteps; r++) {
91
+ vec3 p=from+(s+zoffset)*dir;// + vec3(0.,0.,zoffset);
92
+ p = abs(vec3(tile)-mod(p,vec3(tile*2.))); // tiling fold
93
+ float pa,a=pa=0.;
94
+ for (int i=0; i<iterations; i++) {
95
+ p=abs(p)/dot(p,p)-formuparam; // the magic formula
96
+ //p=abs(p)/max(dot(p,p),0.005)-formuparam; // another interesting way to reduce noise
97
+ float D = abs(length(p)-pa); // absolute sum of average change
98
+ a += i > 7 ? min( 12., D) : D;
99
+ pa=length(p);
100
+ }
101
+ //float dm=max(0.,darkmatter-a*a*.001); //dark matter
102
+ a*=a*a; // add contrast
103
+ //if (r>3) fade*=1.-dm; // dark matter, don't render near
104
+ // brightens stuff up a bit
105
+ float s1 = s+zoffset;
106
+ // need closed form expression for this, now that we shift samples
107
+ float fade = pow(distfading,max(0.,float(r)-sampleShift));
108
+ v+=fade;
109
+
110
+ // fade out samples as they approach the camera
111
+ if( r == 0 )
112
+ fade *= 1. - sampleShift;
113
+ // fade in samples as they approach from the distance
114
+ if( r == volsteps-1 )
115
+ fade *= sampleShift;
116
+ v+=vec3(2.*s1,4.*s1*s1,16.*s1*s1*s1*s1)*a*brightness*fade; // coloring based on distance
117
+ s+=stepsize;
118
+ }
119
+ v=mix(vec3(length(v)),v,saturation); //color adjust
120
+ fragColor = vec4(v*.01,1.);
121
+ }
@@ -0,0 +1,219 @@
1
+ // CC0: Reflective hexes
2
+ // Bit of weekend tinkering
3
+ // Some shadow artefacts which are irritating but felt it was overall good enough to share.
4
+
5
+ vec2 round(vec2 v) {
6
+ return floor(v + 0.5);
7
+ }
8
+ #define const
9
+
10
+ #define TIME iTime
11
+ #define RESOLUTION iResolution
12
+
13
+ #define PI 3.141592654
14
+ #define TAU (2.0*PI)
15
+
16
+ #define TOLERANCE 0.0001
17
+ #define MAX_RAY_LENGTH 24.0
18
+ #define MAX_RAY_MARCHES 60
19
+ #define MAX_SHADOW_MARCHES 20
20
+ #define NORM_OFF 0.001
21
+ #define ROT(a) mat2(cos(a), sin(a), -sin(a), cos(a))
22
+
23
+ // License: WTFPL, author: sam hocevar, found: https://stackoverflow.com/a/17897228/418488
24
+ const vec4 hsv2rgb_K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
25
+ vec3 hsv2rgb(vec3 c) {
26
+ vec3 p = abs(fract(c.xxx + hsv2rgb_K.xyz) * 6.0 - hsv2rgb_K.www);
27
+ return c.z * mix(hsv2rgb_K.xxx, clamp(p - hsv2rgb_K.xxx, 0.0, 1.0), c.y);
28
+ }
29
+ // License: WTFPL, author: sam hocevar, found: https://stackoverflow.com/a/17897228/418488
30
+ // Macro version of above to enable compile-time constants
31
+ #define HSV2RGB(c) (c.z * mix(hsv2rgb_K.xxx, clamp(abs(fract(c.xxx + hsv2rgb_K.xyz) * 6.0 - hsv2rgb_K.www) - hsv2rgb_K.xxx, 0.0, 1.0), c.y))
32
+
33
+ const float hoff = 0.0;
34
+ const float stepf = 0.8;
35
+ const vec3 skyCol = HSV2RGB(vec3(hoff+0.57, 0.70, 0.25));
36
+ const vec3 sunCol1 = HSV2RGB(vec3(hoff+0.60, 0.50, 0.5));
37
+ const vec3 sunCol2 = HSV2RGB(vec3(hoff+0.05, 0.75, 25.0));
38
+ const vec3 diffCol = HSV2RGB(vec3(hoff+0.60, 0.75, 0.25));
39
+ const vec3 sunDir1 = normalize(vec3(3., 3.0, -7.0));
40
+
41
+ // License: Unknown, author: nmz (twitter: @stormoid), found: https://www.shadertoy.com/view/NdfyRM
42
+ vec3 sRGB(vec3 t) {
43
+ return mix(1.055*pow(t, vec3(1./2.4)) - 0.055, 12.92*t, step(t, vec3(0.0031308)));
44
+ }
45
+
46
+ // License: Unknown, author: Matt Taylor (https://github.com/64), found: https://64.github.io/tonemapping/
47
+ vec3 aces_approx(vec3 v) {
48
+ v = max(v, 0.0);
49
+ v *= 0.6;
50
+ float a = 2.51;
51
+ float b = 0.03;
52
+ float c = 2.43;
53
+ float d = 0.59;
54
+ float e = 0.14;
55
+ return clamp((v*(a*v+b))/(v*(c*v+d)+e), 0.0, 1.0);
56
+ }
57
+
58
+ // License: MIT, author: Inigo Quilez, found: https://iquilezles.org/articles/distfunctions/
59
+ float rayPlane(vec3 ro, vec3 rd, vec4 p) {
60
+ return -(dot(ro,p.xyz)+p.w)/dot(rd,p.xyz);
61
+ }
62
+
63
+ // License: MIT, author: Inigo Quilez, found: https://iquilezles.org/www/articles/distfunctions2d/distfunctions2d.htm
64
+ float box(vec2 p, vec2 b) {
65
+ vec2 d = abs(p)-b;
66
+ return length(max(d,0.0)) + min(max(d.x,d.y),0.0);
67
+ }
68
+
69
+ // License: Unknown, author: Martijn Steinrucken, found: https://www.youtube.com/watch?v=VmrIDyYiJBA
70
+ vec2 hextile(inout vec2 p) {
71
+ // See Art of Code: Hexagonal Tiling Explained!
72
+ // https://www.youtube.com/watch?v=VmrIDyYiJBA
73
+ const vec2 sz = vec2(1.0, sqrt(3.0));
74
+ const vec2 hsz = 0.5*sz;
75
+
76
+ vec2 p1 = mod(p, sz)-hsz;
77
+ vec2 p2 = mod(p - hsz, sz)-hsz;
78
+ vec2 p3 = dot(p1, p1) < dot(p2, p2) ? p1 : p2;
79
+ vec2 n = ((p3 - p + hsz)/sz);
80
+ p = p3;
81
+
82
+ n -= vec2(0.5);
83
+ // Rounding to make hextile 0,0 well behaved
84
+ return round(n*2.0)*0.5;
85
+ }
86
+
87
+ // License: MIT, author: Inigo Quilez, found: https://iquilezles.org/articles/distfunctions/
88
+ float hexPrism(vec3 p, vec2 h) {
89
+ const vec3 k = 0.5*vec3(-sqrt(3.0), 1.0, sqrt(4.0/3.0));
90
+ p = abs(p);
91
+ p.xy -= 2.0*min(dot(k.xy, p.xy), 0.0)*k.xy;
92
+ vec2 d = vec2(
93
+ length(p.xy-vec2(clamp(p.x,-k.z*h.x,k.z*h.x), h.x))*sign(p.y-h.x),
94
+ p.z-h.y );
95
+ return min(max(d.x,d.y),0.0) + length(max(d,0.0));
96
+ }
97
+
98
+ float df(vec3 p) {
99
+ vec3 p0 = p.zyx;
100
+ p0.xy -= 0.1*TIME;
101
+ vec2 n0 = hextile(p0.yx);
102
+ float pp = n0.x-0.25*n0.y-0.5*TIME;
103
+ p0.z += 0.2*sin(pp);
104
+ p0.zy *= ROT(-0.2*cos(pp));
105
+ return hexPrism(p0, vec2(0.425, 0.25))-0.075;
106
+ }
107
+
108
+ vec3 normal(vec3 pos) {
109
+ vec2 eps = vec2(NORM_OFF,0.0);
110
+ vec3 nor;
111
+ nor.x = df(pos+eps.xyy) - df(pos-eps.xyy);
112
+ nor.y = df(pos+eps.yxy) - df(pos-eps.yxy);
113
+ nor.z = df(pos+eps.yyx) - df(pos-eps.yyx);
114
+ return normalize(nor);
115
+ }
116
+
117
+ float rayMarch(vec3 ro, vec3 rd, float initt) {
118
+ float t = initt;
119
+ const float tol = TOLERANCE;
120
+ vec2 dti = vec2(1e10,0.0);
121
+ int i = 0;
122
+ for (i = 0; i < MAX_RAY_MARCHES; ++i) {
123
+ float d = df(ro + rd*t);
124
+ if (d<dti.x) { dti=vec2(d,t); }
125
+ if (d < TOLERANCE || t > MAX_RAY_LENGTH) {
126
+ break;
127
+ }
128
+ t += stepf*d;
129
+ }
130
+ if(i==MAX_RAY_MARCHES) { t=dti.y; };
131
+ return t;
132
+ }
133
+
134
+ float softShadow(vec3 ps, vec3 ld, float mint, float k) {
135
+ float res = 1.0;
136
+ float t = mint*3.0;
137
+ for (int i=0; i<MAX_SHADOW_MARCHES; ++i) {
138
+ vec3 p = ps + ld*t;
139
+ float d = df(p);
140
+ res = min(res, k*d/t);
141
+ if (res < TOLERANCE) break;
142
+
143
+ t += max(d, mint);
144
+ }
145
+ return clamp(res, 0.0, 1.0);
146
+ }
147
+
148
+ vec3 render0(vec3 ro, vec3 rd) {
149
+ vec3 col = vec3(0.0);
150
+ float sd = max(dot(sunDir1, rd), 0.0);
151
+ float sf = 1.0001-sd;
152
+ col += 0.5*skyCol*pow((1.0-abs(rd.y)), 8.0);
153
+ col += sunCol1*pow(sd, 100.0);
154
+ col += sunCol2*pow(sd, 800.0);
155
+
156
+ float tp1 = rayPlane(ro, rd, vec4(vec3(0.0, -1.0, 0.0), 6.0));
157
+
158
+ if (tp1 > 0.0) {
159
+ vec3 pos = ro + tp1*rd;
160
+ vec2 pp = pos.xz;
161
+ float db = box(pp, vec2(5.0, 9.0))-3.0;
162
+
163
+ col += vec3(4.0)*skyCol*rd.y*rd.y*smoothstep(0.25, 0.0, db);
164
+ col += vec3(0.8)*skyCol*exp(-0.5*max(db, 0.0));
165
+ col += 0.25*sqrt(skyCol)*max(-db, 0.0);
166
+ }
167
+
168
+ return clamp(col, 0.0, 10.0);;
169
+ }
170
+
171
+ vec3 render(vec3 ro, vec3 rd) {
172
+ float initt = -(ro.x-2.0/3.0)/rd.x;
173
+ float t = rayMarch(ro, rd, initt);
174
+ vec3 p = ro+rd*t;
175
+ vec3 n = normal(p);
176
+ vec3 r = reflect(rd, n);
177
+ vec3 ld = sunDir1;
178
+ const float soff = 0.0001;
179
+ float sd = softShadow(p+soff*n, ld, 0.0125, 3.0);
180
+ float dif = max(dot(ld, n), 0.0);
181
+ dif *= dif;
182
+ dif *= dif;
183
+ vec3 rcol = render0(p, r);
184
+ vec3 col = vec3(0.0);
185
+ if (t < MAX_RAY_LENGTH) {
186
+ col = diffCol;
187
+ col *= mix(0.2, 1.0, dif);
188
+ col *= mix(0.2, 1.0, abs(sd));
189
+ col += rcol*sd;
190
+ }
191
+ return col;
192
+ }
193
+
194
+ vec3 effect(vec2 p) {
195
+ const vec3 ro = .66*vec3(5.0, -1., 1.3);
196
+ // const vec3 ro = 0.8*vec3(5.0, 0.0, 0.0);
197
+ const vec3 la = vec3(0.0, 0.0, 0.0);
198
+ const vec3 up = normalize(vec3(0.0, 1.0, 0.3));
199
+ const vec3 ww = normalize(la - ro);
200
+ const vec3 uu = normalize(cross(up, ww));
201
+ const vec3 vv = (cross(ww,uu));
202
+ const float fov = tan(TAU/6.);
203
+ vec3 rd = normalize(-p.x*uu + p.y*vv + fov*ww);
204
+ vec3 col = render(ro, rd);
205
+ return col;
206
+ }
207
+
208
+ void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
209
+ vec2 q = fragCoord/RESOLUTION.xy;
210
+ vec2 p = -1. + 2. * q;
211
+ vec2 pp = p;
212
+ p.x *= RESOLUTION.x/RESOLUTION.y;
213
+ vec3 col = vec3(0.0);
214
+ col = effect(p);
215
+ col *= smoothstep(1.5, 0.75, length(pp));
216
+ col = aces_approx(col);
217
+ col = sRGB(col);
218
+ fragColor = vec4(col, 1.0);
219
+ }
data/fastlane/Fastfile ADDED
@@ -0,0 +1,76 @@
1
+ # -*- mode: ruby -*-
2
+
3
+
4
+ require 'yaml'
5
+
6
+
7
+ def config(key, defval = nil)
8
+ $config ||= YAML.load_file(File.expand_path '../config.yml', __dir__) rescue {}
9
+ key = key.to_s.upcase
10
+ ENV[key] or $config[key] or defval or raise "missing #{key}"
11
+ end
12
+
13
+ def project()
14
+ "#{config :app_name}.xcodeproj"
15
+ end
16
+
17
+ def workspace()
18
+ "#{config :app_name}.xcworkspace"
19
+ end
20
+
21
+
22
+ default_platform(:ios)
23
+
24
+ platform :ios do
25
+ lane :setup_code_signing do
26
+ type = config :match_type, 'Development'
27
+ identity = type == 'Development' ? type : 'Distribution'
28
+ update_code_signing_settings(
29
+ path: project,
30
+ team_id: config(:team_id),
31
+ code_sign_identity: "Apple #{identity}",
32
+ profile_name: "match #{type} #{config :app_id}",
33
+ use_automatic_signing: false)
34
+ end
35
+
36
+ match_params = -> {{
37
+ team_id: config(:team_id),
38
+ app_identifier: config(:app_id),
39
+ git_url: config(:certs_url),
40
+ git_branch: config(:app_name)
41
+ }}
42
+
43
+ lane :match_update do
44
+ %w[development adhoc appstore].each do |type|
45
+ sync_code_signing type: type, **match_params.call
46
+ end
47
+ end
48
+
49
+ lane :match_fetch do
50
+ %w[development adhoc appstore].each do |type|
51
+ sync_code_signing type: type, **match_params.call, readonly: true
52
+ end
53
+ end
54
+
55
+ lane :match_delete do
56
+ %w[development distribution].each do |type|
57
+ match_nuke(type: type)
58
+ end
59
+ end
60
+
61
+ upload_params = -> {{
62
+ apple_id: config(:apple_id),
63
+ team_id: config(:team_id),
64
+ app_identifier: config(:app_id)
65
+ }}
66
+
67
+ desc "Upload to TestFlight"
68
+ lane :release_testflight do
69
+ params = upload_params.call
70
+ params.update({changelog: config(:changelog)})
71
+
72
+ sync_code_signing type: 'appstore', readonly: true, **match_params.call
73
+ build_app workspace: workspace, scheme: config(:app_name)
74
+ upload_to_testflight **params
75
+ end
76
+ end
@@ -0,0 +1 @@
1
+ 2023 xord.org
@@ -0,0 +1,5 @@
1
+ Solitaire in Space is a card game for everyone, from beginners to experts. Clean graphics and simple controls combine to enhance your gaming experience. The game offers a pleasant and immersive gameplay that will make you lose track of time.
2
+
3
+ Playing solitaire is a relaxing way to relieve everyday stress. Pleasant animations and smooth controls add to the pleasure of lining up the cards. The game also keeps track of daily scores, allowing players to compete for the best score of the day.
4
+
5
+ Space Solitaire is an essential app for lovers of card games, download it from the App Store and enjoy an optimal solitaire experience. Lose track of time and relieve stress as you line up your cards. More addictive gameplay than ever awaits you.
@@ -0,0 +1 @@
1
+ playing,card,cards,game,ruby,klondike,free,shader,glsl,processing
@@ -0,0 +1 @@
1
+ https://xord.org/rubysolitaire/
@@ -0,0 +1 @@
1
+ Solitaire in Space
@@ -0,0 +1 @@
1
+ https://xord.org/rubysolitaire/privacy_policy.html
@@ -0,0 +1 @@
1
+ Enjoy the best Solitaire experience with "Solitaire in Space"! Vibrant graphics, intuitive controls, and addictive gameplay await you. Lose track of time as you arrange the cards, relieving stress along the way. It's the best choice for Solitaire enthusiasts.
@@ -0,0 +1 @@
1
+ - Fixed some minor bugs
@@ -0,0 +1 @@
1
+ Several card designs and game backgrounds to choose from
@@ -0,0 +1 @@
1
+ https://xord.org/rubysolitaire/
@@ -0,0 +1,5 @@
1
+ 「宇宙ソリティア」は初心者から上級者まで、誰にでも楽しめるソリティアゲームです。美しいグラフィックとシンプルな操作性が組み合わさり、あなたのゲーム体験をさらに一層向上させます。このゲームは、時間を忘れて没頭できる心地よいゲームプレイを提供します。
2
+
3
+ ソリティアをプレイすることで、日常のストレスを解消し、リラックスできるひとときを過ごせます。繊細なアニメーションと滑らかな操作により、カードを並べる喜びがさらに高まります。また、日ごとのスコアが記録されるため、その日のベストスコアを競うこともできます。
4
+
5
+ 「宇宙ソリティア」は、カードゲームの愛好家にとっては欠かせないアプリです。App Storeからダウンロードして、最適なソリティア体験をお楽しみください。時間を忘れ、ストレスを解消しながらカードを並べましょう。今まで以上に中毒性の高いゲームプレイがあなたを待っています。
@@ -0,0 +1 @@
1
+ そりてぃあ,とらんぷ,かーど,げーむ,ルビー,るびー,クロンダイク,くろんだいく,無料
@@ -0,0 +1 @@
1
+ https://xord.org/rubysolitaire/
@@ -0,0 +1 @@
1
+ 宇宙ソリティア トランプカードゲーム
@@ -0,0 +1 @@
1
+ https://xord.org/rubysolitaire/privacy_policy.html