Adjust sourcize.c to use _snprintf if using MSVC.
[SquirrelJME.git] / nanocoat / src / modelessStars.c
blob757fd31b10f85452dc254d34cee856ac6f0e7933
1 /* -*- Mode: C; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
3 // SquirrelJME
4 // Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
5 // ---------------------------------------------------------------------------
6 // SquirrelJME is under the Mozilla Public License Version 2.0.
7 // See license.mkd for licensing and copyright information.
8 // -------------------------------------------------------------------------*/
10 #include "sjme/nvm/modelessStars.h"
12 sjme_errorCode sjme_modelessStars(
13 sjme_attrInOutNotNull sjme_modelessStarState* state,
14 sjme_attrInNotNull uint32_t* buf,
15 sjme_attrInPositiveNonZero sjme_jint width,
16 sjme_attrInPositiveNonZero sjme_jint height,
17 sjme_attrInPositiveNonZero sjme_jint pitch,
18 sjme_attrInValue sjme_jint tick)
20 sjme_modelessStar* modelessStar;
21 uint32_t* bufSlice;
22 sjme_modelessStarColor colors[SJME_NUM_MODELESS_STAR_COLOR_IDS];
23 sjme_modelessStarColor* startColor;
24 sjme_modelessStarColor* endColor;
25 sjme_modelessStarColor* atColor;
26 sjme_modelessStarColor* sliceColor;
27 sjme_jint h, y, x, next;
28 sjme_juint rawHex;
30 /* Make sure input values are fine. */
31 if (state == NULL || buf == NULL || width <= 0 || height <= 0 ||
32 pitch <= 0)
33 return SJME_ERROR_INVALID_ARGUMENT;
35 /* Easier pointers. */
36 startColor = &colors[SJME_MODELESS_STAR_COLOR_ID_START];
37 endColor = &colors[SJME_MODELESS_STAR_COLOR_ID_END];
38 atColor = &colors[SJME_MODELESS_STAR_COLOR_ID_AT];
39 sliceColor = &colors[SJME_MODELESS_STAR_COLOR_ID_SLICE];
41 /* Set base color information. */
42 startColor->xrgb[0] = 0x00 << SJME_MODELESS_STAR_COLOR_SHIFT;
43 startColor->xrgb[1] = 0x5B << SJME_MODELESS_STAR_COLOR_SHIFT;
44 startColor->xrgb[2] = 0xCE << SJME_MODELESS_STAR_COLOR_SHIFT;
45 startColor->xrgb[3] = 0xFA << SJME_MODELESS_STAR_COLOR_SHIFT;
46 endColor->xrgb[0] = 0x00 << SJME_MODELESS_STAR_COLOR_SHIFT;
47 endColor->xrgb[1] = 0xF5 << SJME_MODELESS_STAR_COLOR_SHIFT;
48 endColor->xrgb[2] = 0xA9 << SJME_MODELESS_STAR_COLOR_SHIFT;
49 endColor->xrgb[3] = 0xB8 << SJME_MODELESS_STAR_COLOR_SHIFT;
51 /* Set middle color. */
52 for (x = 0; x < 4; x++)
54 /* Set starting color. */
55 atColor->xrgb[x] =
56 startColor->xrgb[x];
58 /* Set slice color. */
59 if (endColor->xrgb[x] != startColor->xrgb[x])
60 sliceColor->xrgb[x] = (endColor->xrgb[x] -
61 startColor->xrgb[x]) / height;
62 else
63 sliceColor->xrgb[x] = 0;
66 /* Draw in each color slice. */
67 for (h = 0; h < height; h++)
69 /* Determine where to draw in the slice. */
70 bufSlice = &buf[pitch * h];
72 /* Determine the actual color hex. */
73 rawHex = 0;
74 for (x = 0; x < 4; x++)
76 rawHex <<= 8;
77 rawHex |= (atColor->xrgb[x] >>
78 SJME_MODELESS_STAR_COLOR_SHIFT) & 0xFF;
81 /* Just set it all to that color. */
82 for (x = 0; x < width; x++)
83 bufSlice[x] = rawHex;
85 /* Shift color closer. */
86 for (x = 0; x < 4; x++)
88 /* If already at this color, do not go there. */
89 next = atColor->xrgb[x];
90 if (next == endColor->xrgb[x])
91 continue;
93 /* Determine next color. */
94 next += sliceColor->xrgb[x];
96 /* Make sure color stays in bounds. */
97 if (next > 0xFF0000)
98 next = 0xFF0000;
99 else if (next < 0x000000)
100 next = 0x000000;
102 /* Go to this color. */
103 atColor->xrgb[x] = next;
107 /* Draw random star positions. */
108 for (h = 0; h < SJME_MODELESS_STAR_COUNT; h++)
110 /* Get this star. */
111 modelessStar = &state->modelessStars[h];
113 /* Does this star need to be initialized? */
114 if (modelessStar->shining == SJME_JNI_FALSE)
116 /* Not creating stars yet, and is not shining. */
117 if (state->lockStarCreation > 0)
119 /* Count down though... */
120 state->lockStarCreation--;
122 continue;
125 /* Star is shining now. */
126 modelessStar->shining = SJME_JNI_TRUE;
128 /* Set random position on the screen. */
129 if (state->latchedFirstGo)
130 modelessStar->x = width - 1;
131 else
132 modelessStar->x = rand() % width;
133 modelessStar->y = rand() % height;
135 /* Set a random speed for the star. */
136 modelessStar->speed = (rand() % 4) + 1;
138 /* Do not initialize another star just yet. */
139 state->lockStarCreation = (tick % 25) + (rand() % 50);
140 state->lockStarCreationLast = state->lockStarCreation;
143 /* Move star to the left. */
144 modelessStar->x -= modelessStar->speed;
146 /* Did the star fall off the screen? */
147 if (modelessStar->x < 0)
149 modelessStar->shining = SJME_JNI_FALSE;
151 /* Do not draw this star. */
152 continue;
155 /* Draw star. */
156 x = modelessStar->x;
157 y = modelessStar->y;
158 buf[(pitch * y) + x] = 0x00FFFFFF;
160 /* Do this step again to tick some more? */
161 if (!state->latchedFirstGo)
163 /* Reset counter. */
164 h = -1;
166 /* No longer the first go. */
167 state->latchedFirstGo = SJME_JNI_TRUE;
171 /* Handled successfully. */
172 return SJME_JNI_TRUE;