Initial commit

This commit is contained in:
aNNiMON 2024-02-13 23:58:29 +02:00
commit 9474e6e25e
19 changed files with 1899 additions and 0 deletions

8
.classpath Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

33
.project Normal file
View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>VisualME</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

34
AndroidManifest.xml Normal file
View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.annimon.visualme"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
<activity
android:name=".MainActivity" >
<intent-filter>
<action android:name="com.annimon.visualme.MainActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".SettingsActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

5
proguard-project.txt Normal file
View File

@ -0,0 +1,5 @@
@E:\\SETUPS\\Disk\\Programming\\Java\\android.pro
-obfuscationdictionary E:\\SETUPS\\Disk\\Programming\\Java\\compact.txt
-optimizationpasses 9
-allowaccessmodification
-overloadaggressively

14
project.properties Normal file
View File

@ -0,0 +1,14 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
target=android-16

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

30
res/values-ru/strings.xml Normal file
View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">VisualME</string>
<string name="run">Запустить VisualME</string>
<string name="show_fps">Показывать fps</string>
<string name="num_of_branches">Количество ветвей</string>
<string name="flexibility">Гибкость</string>
<string name="flexibility_summary">Количество звеньев в линии</string>
<string name="proportions">Пропорции экрана</string>
<string name="speed">Скорость</string>
<string name="change_visualization">Автосмена визуализаций?</string>
<string name="autochangevis_summary">Автоматически изменять режим визуализации?</string>
<string name="change_figures">Автосмена фигур?</string>
<string name="autochangefig_summary">Автоматически изменять тип рисуемых фигур?</string>
<string name="shape_type">Тип фигуры</string>
<string-array name="shape_type_entries">
<item>Линия</item>
<item>Эллипс</item>
<item>Квадрат</item>
</string-array>
<string-array name="shape_type_values">
<item>0</item>
<item>1</item>
<item>2</item>
</string-array>
</resources>

30
res/values/strings.xml Normal file
View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">VisualME</string>
<string name="run">Run VisualME</string>
<string name="show_fps">Show fps</string>
<string name="num_of_branches">Number of branches</string>
<string name="flexibility">Flexibility</string>
<string name="flexibility_summary">Number of elements in line</string>
<string name="proportions">Screen proportions</string>
<string name="speed">Speed</string>
<string name="change_visualization">Change visualization?</string>
<string name="autochangevis_summary">Automatically change visualization mode?</string>
<string name="change_figures">Change figures?</string>
<string name="autochangefig_summary">Automatically change drawing figures?</string>
<string name="shape_type">Shape type</string>
<string-array name="shape_type_entries">
<item>Line</item>
<item>Ellipse</item>
<item>Square</item>
</string-array>
<string-array name="shape_type_values">
<item>0</item>
<item>1</item>
<item>2</item>
</string-array>
</resources>

54
res/xml/visualme.xml Normal file
View File

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/app_name" >
<Preference android:title="@string/run" >
<intent android:action="com.annimon.visualme.MainActivity" />
</Preference>
<CheckBoxPreference
android:defaultValue="false"
android:key="show_fps"
android:title="@string/show_fps" />
<EditTextPreference
android:defaultValue="15"
android:inputType="number"
android:key="branches"
android:title="@string/num_of_branches" />
<EditTextPreference
android:defaultValue="20"
android:inputType="number"
android:key="flexibility"
android:summary="@string/flexibility_summary"
android:title="@string/flexibility" />
<EditTextPreference
android:defaultValue="4"
android:inputType="number"
android:key="proportions"
android:title="@string/proportions" />
<EditTextPreference
android:defaultValue="1"
android:inputType="number"
android:key="speed"
android:title="@string/speed" />
<ListPreference
android:defaultValue="0"
android:entries="@array/shape_type_entries"
android:entryValues="@array/shape_type_values"
android:key="shape_type"
android:title="@string/shape_type" />
<CheckBoxPreference
android:defaultValue="true"
android:key="autochangevis"
android:summary="@string/autochangevis_summary"
android:title="@string/change_visualization" />
<CheckBoxPreference
android:defaultValue="false"
android:key="autochangefig"
android:summary="@string/autochangefig_summary"
android:title="@string/change_figures" />
</PreferenceScreen>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,35 @@
/* By aNNiMON from GipGameActivity */
package com.annimon.visualme;
public class Fps {
private static final int MAX_FPS = 30;
private static final int MAX_DELAY = 1000 / MAX_FPS;
private static long currentFps;
private static long counter = 0, startTime = 0;
private static long startTimeForMeasureDelay = 0;
public static String getFpsAsString() {
counter++;
if (startTime == 0) {
startTime = System.currentTimeMillis();
}
if ((System.currentTimeMillis() - startTime) >= 1000) {
currentFps = counter;
counter = 0;
startTime = System.currentTimeMillis();
}
return Long.toString(currentFps);
}
public static void startMeasuringDelay() {
startTimeForMeasureDelay = System.currentTimeMillis();
}
public static long getDelay() {
long delay = System.currentTimeMillis() - startTimeForMeasureDelay;
return (delay > MAX_DELAY ? 0 : MAX_DELAY - delay);
}
}

View File

@ -0,0 +1,146 @@
package com.annimon.visualme;
import com.annimon.visualme.visuals.Visual;
import com.annimon.visualme.visuals.VisualME;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.preference.PreferenceManager;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class GameSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
private static final int BACKGROUND_COLOR = 0xff000000;
private boolean showFps;
private Paint paint;
private SurfaceHolder surfaceHolder;
private DrawingThread thread;
private Visual visual;
public GameSurfaceView(Context context) {
super(context);
surfaceHolder = getHolder();
surfaceHolder.addCallback(this);
visual = new VisualME();
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
showFps = pref.getBoolean("show_fps", false);
if (visual instanceof VisualME) {
VisualME vis = (VisualME) visual;
vis.setNumberOfBranches( Integer.parseInt(pref.getString("branches", "15")) );
vis.setFlexibility( Integer.parseInt(pref.getString("flexibility", "20")) );
vis.setScreenProportions( Integer.parseInt(pref.getString("proportions", "4")) );
vis.setSpeed( Integer.parseInt(pref.getString("speed", "1")) );
vis.setShapeType( Integer.parseInt(pref.getString("shape_type", "0")) );
vis.setVisualizationAutochange( pref.getBoolean("autochangevis", true) );
vis.setShapeAutochange( pref.getBoolean("autochangefig", false) );
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.FILL);
thread = new DrawingThread();
thread.keepRunning = true;
thread.start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int newW, int newH) {
visual.sizeChanged(newW, newH);
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
thread.keepRunning = false;
boolean retry = true;
while (retry) {
try {
thread.join();
retry = false;
paint = null;
thread = null;
} catch (InterruptedException e) {
}
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
visual.onTouch((int) event.getX(), (int)event.getY());
return true;
}
return super.onTouchEvent(event);
}
@Override
protected void onDraw(Canvas canvas) {
// Fill background
paint.setColor(BACKGROUND_COLOR);
canvas.drawPaint(paint);
visual.paint(canvas, paint);
// Draw FPS
if (showFps) {
paint.setColor(Color.WHITE);
canvas.drawText(Fps.getFpsAsString(), 10, 10, paint);
}
}
private void update() {
visual.update();
}
private class DrawingThread extends Thread {
public boolean keepRunning = true;
@Override
public void run() {
Canvas c;
while (keepRunning) {
Fps.startMeasuringDelay();
update();
c = null;
try {
c = surfaceHolder.lockCanvas();
if (c != null) {
synchronized (surfaceHolder) {
onDraw(c);
}
}
} finally {
if (c != null) {
surfaceHolder.unlockCanvasAndPost(c);
}
}
try {
Thread.sleep(Fps.getDelay());
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
}
}

View File

@ -0,0 +1,23 @@
package com.annimon.visualme;
import android.app.Activity;
import android.os.Bundle;
import android.view.WindowManager;
public class MainActivity extends Activity {
private GameSurfaceView gameView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Turn on the backlight
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
gameView = new GameSurfaceView(this);
gameView.setFocusable(true);
setContentView(gameView);
}
}

View File

@ -0,0 +1,14 @@
package com.annimon.visualme;
import android.os.Bundle;
import android.preference.PreferenceActivity;
public class SettingsActivity extends PreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.visualme);
}
}

View File

@ -0,0 +1,24 @@
package com.annimon.visualme.visuals;
import android.graphics.Canvas;
import android.graphics.Paint;
public abstract class Visual {
protected int width, height;
public void sizeChanged(int width, int height) {
this.width = width;
this.height = height;
init();
}
public abstract void init();
public abstract void paint(Canvas canvas, Paint paint);
public abstract void onTouch(int x, int y);
public abstract void update();
}

View File

@ -0,0 +1,403 @@
package com.annimon.visualme.visuals;
import java.util.Random;
import com.annimon.visualme.FastMath;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
public class VisualME extends Visual {
private static final int MAX_DELTA_COLOR = 20;
protected static final Random random = new Random();
// Îñíîâíûå ïàðàìåòðû âèçóàëèçàöèè
private int numberOfBranches;
private int flexibility;
private float screenProportions;
private int shapeType;
private int speed;
// Ïàðàìåòðû ñîñòîÿíèé
private boolean shapeAutochange;
private boolean visualizationAutochange;
// Ñîñòîÿíèÿ èçìåíåíèÿ êîìïîíåíò öâåòà
private boolean redChange, greenChange, blueChange;
private int rc, gc, bc;
private int rgbChangeMode, visualMode, colorMode;
private int startAngleInt;
private float angleDelta;// Óãîë ìåæäó âåòâÿìè
private float len; // Äëèíà îäíîãî çâåíà
private float[] angles;
private Thread thr;
public void init() {
// Öâåòà (ïåðåõîäû)
rc = 0;
gc = 0;
bc = 0;
// Ðåæèì èçìåíåíèÿ öâåòîâ (ïåðåõîäîâ)
rgbChangeMode = 1;
// Âèä âèçóàëèçàöèè
visualMode = 1;
// Ðåæèì ïåðåõîäîâ öâåòîâ
colorMode = 1;
// Íà÷àëüíûé óãîë ïîâîðîòà âåòâè
startAngleInt = random.nextInt(360);
// Âû÷èñëÿåì íåîáõîäèìûå ïàðàìåòðû
if (width > height) {
len = height / screenProportions / flexibility;
} else {
len = width / screenProportions / flexibility;
}
thr = new Thread(new Runnable() {
@Override
public void run() {
while (thr == Thread.currentThread()) {
threadUpdate();
}
}
});
thr.start();
}
/**
* Óñòàíîâêà ãèáêîñòè âåòâåé.
* @param flexibility çíà÷åíèå ãèáêîñòè.
*/
public void setFlexibility(int flexibility) {
this.flexibility = flexibility;
angles = new float[flexibility];
}
/**
* Óñòàíîâêà êîëè÷åñòâà âåòâåé.
* @param numberOfBranches
*/
public void setNumberOfBranches(int numberOfBranches) {
this.numberOfBranches = numberOfBranches;
// Óãîë ìåæäó âåòâÿìè
angleDelta = (float) (2 * FastMath.PI / numberOfBranches);
}
/**
* Óñòàíîâêà ïðîïîðöèé ýêðàíà è âèçóàëèçàöèè.
* @param screenProportions
*/
public void setScreenProportions(int screenProportions) {
this.screenProportions = 4f / screenProportions;
}
/**
* Óñòàíîâêà îòîáðàæàåìûõ ôèãóð (ëèíèÿ, òåêñò, è ò.ä.).
* @param shapeType
*/
public void setShapeType(int shapeType) {
this.shapeType = shapeType;
}
/**
* Óñòàíîâêà ñêîðîñòè àíèìàöèè.
* @param speed
*/
public void setSpeed(int speed) {
this.speed = 10 - speed;
}
/**
* Óñòàíîâêà àâòîñìåíû ôèãóð.
* @param shapeAutochange
*/
public void setShapeAutochange(boolean shapeAutochange) {
this.shapeAutochange = shapeAutochange;
}
/**
* Óñòàíîâêà àâòîñìåíû âèçóàëèçàöèè.
* @param visualizationAutochange
*/
public void setVisualizationAutochange(boolean visualizationAutochange) {
this.visualizationAutochange = visualizationAutochange;
}
@Override
public void paint(Canvas canvas, Paint paint) {
if (random.nextInt(20) == 5) startAngleInt = random.nextInt(360);
// Íà÷àëüíûé óãîë
float startAngle = (float) (startAngleInt * FastMath.PI / 180);
// Èíòåðïîëÿöèÿ óãëîâ ìåæäó ùóïàëüöàìè
angles[0] = (float) (angles[0] + FastMath.sin(startAngle) / speed);
for (int i = 1; i < flexibility; i++) {
angles[i] = (float) (angles[i] + (angles[i - 1] - angles[i]) * 0.1);
}
//String currentTime = "";
//if (shapeType == 3) currentTime = time2fileName();
for (int j = 0; j < numberOfBranches; j++) {
float x = 0.5f * width;
float y = 0.5f * height;
float tx = 0, ty = 0;
final float temp1 = j * angleDelta + angles[1];
for (int i = 1; i < flexibility; i++) {
final float temp2 = j * angleDelta + angles[i];
if (visualMode == 1) {
tx = (float) (x + FastMath.cos(temp1) * len);
ty = (float) (y + FastMath.sin(temp2) * len);
x = x + (float) (FastMath.cos(temp2) * len);
}
else if (visualMode == 2) {
tx = (float) (x + FastMath.sin(temp2) * len);
ty = (float) (y + FastMath.cos(temp2) * len);
}
else if (visualMode == 3) {
tx = (float) (x + FastMath.tan(temp1) * len);
ty = (float) (y + FastMath.cos(temp2) * len);
y = y - (float) (FastMath.sin(temp2) * len);
}
else if (visualMode == 4) {
tx = (float) (x + FastMath.tan(temp1) * len);
ty = (float) (y + FastMath.cos(temp2) * len);
x = y - (float) (FastMath.sin(temp2) * len);
}
else if (visualMode == 5) {
tx = (float) (x + FastMath.tan(temp1) * len);
ty = (float) (y + FastMath.cos(temp2) * len);
x = x * ty * angleDelta + angles[i] - (float) (FastMath.sin(temp2) * len);
}
else if (visualMode == 6) {
x = x + (float) (FastMath.sin(temp2) * len);
y = y + (float) (FastMath.cos(temp2) * len);
tx = (float) (x + FastMath.cos(temp1) * len);
ty = (float) (y + FastMath.sin(temp1) * len);
x = x + (float) (FastMath.sin(temp2) * len);
y = y + (float) (FastMath.cos(temp2) * len);
}
if (colorMode == 1) setColor(paint, rc, gc, bc);
else {
final int deltaColor = 255 - 255 * i / flexibility;
if (colorMode == 2) setColor(paint, deltaColor, 0, 255);
else if (colorMode == 3) setColor(paint, deltaColor, 255, 0);
else if (colorMode == 4) setColor(paint, deltaColor, 255, 255);
else if (colorMode == 5) setColor(paint, 0, deltaColor, 255);
else if (colorMode == 6) setColor(paint, 255, deltaColor, 0);
else if (colorMode == 7) setColor(paint, 255, deltaColor, 255);
else if (colorMode == 8) setColor(paint, 0, 255, deltaColor);
else if (colorMode == 9) setColor(paint, 255, 0, deltaColor);
else if (colorMode == 10) setColor(paint, 255, 255, deltaColor);
else if (colorMode == 11) setColor(paint, deltaColor, deltaColor, 0);
else if (colorMode == 12) setColor(paint, deltaColor, deltaColor, 255);
else if (colorMode == 13) setColor(paint, deltaColor, 0, deltaColor);
else if (colorMode == 14) setColor(paint, deltaColor, 255, deltaColor);
else if (colorMode == 15) setColor(paint, 0, deltaColor, deltaColor);
else if (colorMode == 16) setColor(paint, 255, deltaColor, deltaColor);
else if (colorMode == 17) setColor(paint, rc, deltaColor, 255);
else if (colorMode == 18) setColor(paint, 255, gc, deltaColor);
else if (colorMode == 19) setColor(paint, 255, deltaColor, bc);
else if (colorMode == 20) setColor(paint, bc, rc, deltaColor);
}
if (shapeType == 0) canvas.drawLine(x, y, tx, ty, paint);
else if (shapeType == 1) {
RectF rf = new RectF(tx, ty, x, y);
canvas.drawArc(rf, 0, 360, false, paint);
}
else if (shapeType == 2) canvas.drawRect(tx, ty, x, y, paint);
// else if (shapeType == 3) grf.drawString(currentTime,(int) x, (int) y, 20);
x = tx;
y = ty;
}
}
// Motion-Blur
//grf.drawRGB(backgroundPixels, 0, width, 0, 0, width, height/2, true);
//grf.drawRGB(backgroundPixels, 0, width, 0, height/2, width, height/2, true);
}
@Override
public void onTouch(int x, int y) {
if (y >= (height / 2)) {
colorMode++;
if (colorMode > MAX_DELTA_COLOR) {
colorMode = 1;
}
} else {
visualMode++;
if (visualMode > 6) {
visualMode = 1;
}
}
}
@Override
public void update() {
rgb();
}
public void threadUpdate() {
int i = random.nextInt(40);
if (visualizationAutochange) {
if (i == 16) colorMode = random.nextInt(MAX_DELTA_COLOR) + 1;
else if (i == 19) visualMode = random.nextInt(6) + 1;
}
if (shapeAutochange) if (i == 36) shapeType = random.nextInt(4);
try {
Thread.sleep(800);
} catch (InterruptedException ex) {}
}
private void setColor(Paint paint, int red, int green, int blue) {
paint.setColor(Color.argb(255, red, green, blue));
}
private void rgb() {
if (rgbChangeMode == 1) {
rc++;
if (rc > 253) {
rc--;
redChange = true;
}
if (redChange == true) {
rc = rc - 2;
}
if (rc < 18 && redChange == true) {
rc = 0;
redChange = false;
rgbChangeMode++;
}
}
else if (rgbChangeMode == 2) {
gc++;
if (gc > 253) {
gc--;
greenChange = true;
}
if (greenChange == true) {
gc = gc - 2;
}
if (gc < 18 && greenChange == true) {
gc = 0;
greenChange = false;
rgbChangeMode++;
}
}
else if (rgbChangeMode == 3) {
bc++;
if (bc > 253) {
bc--;
blueChange = true;
}
if (blueChange == true) {
bc = bc - 2;
}
if (bc < 18 && blueChange == true) {
bc = 0;
blueChange = false;
rgbChangeMode++;
}
}
else if (rgbChangeMode == 4) {
rc++;
gc++;
if (rc > 253) {
rc--;
gc--;
redChange = true;
}
if (redChange == true) {
rc = rc - 2;
gc = gc - 2;
}
if (rc < 18 && redChange == true) {
rc = 0;
gc = 0;
redChange = false;
rgbChangeMode++;
}
}
else if (rgbChangeMode == 5) {
rc++;
bc++;
if (rc > 253) {
rc--;
bc--;
redChange = true;
}
if (redChange == true) {
rc = rc - 2;
bc = bc - 2;
}
if (rc < 18 && redChange == true) {
rc = 0;
bc = 0;
redChange = false;
rgbChangeMode++;
}
}
else if (rgbChangeMode == 6) {
gc++;
bc++;
if (gc > 253) {
gc--;
bc--;
greenChange = true;
}
if (greenChange == true) {
gc = gc - 2;
bc = bc - 2;
}
if (gc < 18 && greenChange == true) {
gc = 0;
bc = 0;
greenChange = false;
rgbChangeMode++;
}
}
else if (rgbChangeMode == 7) {
rc++;
gc++;
bc++;
if (gc > 253) {
rc--;
gc--;
bc--;
greenChange = true;
}
if (greenChange == true) {
rc = rc - 2;
gc = gc - 2;
bc = bc - 2;
}
if (gc < 18 && greenChange == true) {
rc = 0;
gc = 0;
bc = 0;
greenChange = false;
rgbChangeMode = 1;
}
}
}
}