Skip to content
This repository has been archived by the owner on Oct 10, 2020. It is now read-only.

Commit

Permalink
Merge pull request #3 from SpencerJ21/release-prep
Browse files Browse the repository at this point in the history
Release prep
  • Loading branch information
jm-spencer committed May 24, 2019
2 parents ce57b5c + 87518dd commit ab97496
Show file tree
Hide file tree
Showing 13 changed files with 586 additions and 327 deletions.
18 changes: 18 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
BasedOnStyle: Google
AlignConsecutiveAssignments: true
AlignTrailingComments: true
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: true
AlwaysBreakTemplateDeclarations: Yes
BreakBeforeBraces: Custom
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: true
AfterNamespace: false
ColumnLimit: 100
DerivePointerAlignment: false
PointerAlignment: Right
Binary file added Example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Field.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2019 Joseph Spencer

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
81 changes: 81 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
ScreenLib
=========
ScreenLib is a PROS library that handles screen drawing functions,
primarily printing each game's field. It provides a powerful way to
draw any possible field without requiring experience with [lvgl](https://littlevgl.com/)

![alt text](./Example.png "Example")

Installing
==========
* Go over to [releases](https://github.com/SpencerJ21/screenlib/releases) and download the latest version
* Open a terminal wherever you downloaded it(try shift + right click in file explorer)
* run `prosv5 c fetch [email protected]`, replacing VERSION with the version
* run `prosv5 c apply screenlib` in your project directory to install

Version
=======
The first digit refers to the vex game: Tower Takeover will be version 1.X.X, while next year's game will be 2.X.X
The second digit refers to any new features that may be added.
The third digit refers to any bug fixes.

License
=======
This software uses the MIT License. See [LICENSE](LICENSE) for more information.

Usage
=====
Object drawing is mostly done through a `Field` object, by giving a position enum class and a bitfield of which cubes to print.
Most objects on the screen are referred to by `left`, `right`, `near`, and `far` (near refers to the bottom of the screen while far refers to the top)

**Make sure screen::initializeStyles() is called during initialization**

Unscored Cubes
--------------
An example of this is:
`field.draw(screen::cubeGroup::right4, 0b01010);`

Let's take a look at how the field is represented
![alt text](./Field.png "Labeled Field")
Each of the cube group names are in the enum class `screen::cubeGroup`,
each of the tower names are in the enum class `screen::tower`, and
each of the scoring zone names are in the enum class `screen::scoringZone`

The numbers on the cube show the bit that represents them in their bitfield:
a 0 means it's looking at bit 0: `0b0000X`
a 1 means it's looking at bit 1: `0b000X0`
and so on.

This is done so the presence of every cube in a group can be given by a number
say you want the cubes labeled 3, 1, and 0, the bitfield would be `0b01011`

For the stacks near the middle, the cubes in the stack but not on top, are still represented by the bits that follow the top cube's bit (the 3 cubes under a cube on bit 3 are represented by bits 2, 1, and 0)

Alternatively, macros can be used for more verbose code; here is the equivalent of the previous example:
`field.draw(screen::cubeGroup::right4, CUBE_HIGHEST + CUBE_2LOWEST);`

`CUBE_HIGHEST` represents the highest cube in the stack, followed by `CUBE_2HIGHEST` (the 2nd highest), followed by `CUBE_2LOWEST` (the 2nd lowest), and finally `CUBE_LOWEST`
As the 4 cube stacks on the left and right are in the same order but slightly different positions, the corresponding cubes are represented the same (purple to purple, orange to orange, green to green)

`CUBE_FAR` and `CUBE_NEAR` are for the cube sectors farLeft and farRight

`CUBE_TOP_NEAR`, `CUBE_FAR_LEFT`, `CUBE_NEAR_LEFT`, `CUBE_FAR_RIGHT`, and `CUBE_NEAR_RIGHT` are used for the five cube stack on the near side

and finally, all macros starting with `TOWER_CUBE_` refer to the cubes around a tower

Scored Cubes
------------
Scored cubes are drawn along with where they are, either in a tower or a scoring zone. In a tower the second parameter describes the color of the cube,
(`screen::color::`). In a scoring zone the second parameter does the same however, two colors can be placed in an array to denote two stacks. In addition,
a third parameter is used to display "stack height", a number printed on top to describe how many cubes are in the stack.
Note: use `screen::color::none` to abstain from printing a scored cube in that position

Example
-------
This directory (specifically [opcontrol.cpp](./src/opcontrol.cpp)) is a usage example (it produces the image at the top of this page)

Acknowledgements
================
smallfont.c is converted version of the digits 0-9 from [Synchronizer NBP Font](https://www.fontspace.com/total-fontgeek-dtf-ltd/synchronizer-nbp) by total FontGeek DTF, Ltd. all credit regarding the font to them.

Thanks to Hotel from the PROS team, Salmon from Okapilib, and Theo from 7842F, for giving some advice on improving the code here
139 changes: 109 additions & 30 deletions include/screen/field.hpp
Original file line number Diff line number Diff line change
@@ -1,24 +1,86 @@
#ifndef SCREEN_FIELD_HPP_
#define SCREEN_FIELD_HPP_
#include "screen/resources.hpp"
#include <vector>
#include "screen/resources.hpp"

namespace screen{

class Field{
public:
#define TOWER_CUBE_FAR 8
#define TOWER_CUBE_RIGHT 4
#define TOWER_CUBE_NEAR 2
#define TOWER_CUBE_LEFT 1

#define CUBE_HIGHEST 8
#define CUBE_2HIGHEST 4
#define CUBE_2LOWEST 2
#define CUBE_LOWEST 1

#define CUBE_FAR 2
#define CUBE_NEAR 1

#define CUBE_TOP_NEAR 16
#define CUBE_NEAR_RIGHT 8
#define CUBE_FAR_RIGHT 4
#define CUBE_NEAR_LEFT 2
#define CUBE_FAR_LEFT 1

/**
* See Field.png on https://github.com/SpencerJ21/screenlib
*
* Each of the cube group names are in screen::cubeGroup,
* each of the tower names are in screen::tower, and
* each of the scoring zone names are in screen::scoringZone
*
* The numbers on the cube show the bit that represents them in their bitfield:
* a 0 means it's looking at bit 0: 0b0000X
* a 1 means it's looking at bit 1: 0b000X0
* and so on.
*
* This is done so the presence of every cube in a group can be given by a number
* say you want the cubes labeled 3, 1, and 0, the bitfield would be 0b01011
*
* For the stacks near the middle, the cubes in the stack but not on top, are still represented by
* the bits that follow the top cube's bit (the 3 cubes under a cube on bit 3 are represented by
* bits 2, 1, and 0)
*
* Alternatively, macros can be used for more verbose code; here is the equivalent of the previous
* example: field.draw(screen::cubeGroup::right4, CUBE_HIGHEST + CUBE_2LOWEST);
*
* CUBE_HIGHEST represents the highest cube in the stack, followed by CUBE_2HIGHEST (the 2nd
* highest), followed by CUBE_2LOWEST (the 2nd lowest), and finally CUBE_LOWEST As the 4 cube stacks
* on the left and right are in the same order but slightly different positions, the corresponding
* cubes are represented the same (purple to purple, orange to orange, green to green)
*
* CUBE_FAR and CUBE_NEAR are for the cube Groups farLeft and farRight
*
* CUBE_TOP_NEAR, CUBE_FAR_LEFT, CUBE_NEAR_LEFT, CUBE_FAR_RIGHT, and CUBE_NEAR_RIGHT are used for
* the five cube stack on the near side
*
* and finally, all macros starting with TOWER_CUBE_ refer to the cubes around a tower
*
*
* Scored cubes are drawn along with where they are, either in a tower or a scoring zone. In a tower
* the second parameter describes the color of the cube, (screen::color::). In a scoring zone the
* second parameter does the same however, two colors can be placed in an array to denote two
* stacks. In addition, a third parameter is used to display "stack height", a number printed on top
* to describe how many cubes are in the stack. Note: use `screen::color::none` to abstain from
* printing a scored cube in that position
*/

namespace screen {

class Field {
public:
/**
* Field generator for the screen
*
* @param parent LVGL object to place upon
* @param x x-value from 0-240 of the leftmost side of the field, default is centered
* @param iautoInit print colored tiles / taped lines immediately, and after each clean
*/
Field(lv_obj_t *parent, const uint8_t x = 120, const bool iautoInit = true);
Field(lv_obj_t *parent, uint8_t x = 120, bool iautoInit = true);
~Field();

/**
* Remove all objects from the field
* Remove all objects from the field, and reset to default
*/
void clean();

Expand All @@ -28,60 +90,70 @@ class Field{
*
* @param x new x-value from 0-240 of the leftmost side of the field
*/
void setX(const uint8_t x);
void setX(uint8_t x);

/**
* draw a group of cubes
*
* @param pos which group of cubes to print - see resources.hpp
* @param presence a bitfield of present cubes. Starts at highest cube as the highest bit,
* or furthest, or leftmost, depending on which group
* or furthest, or leftmost, depending on which group. See the README for more information
*/
void drawCubeGroup(const CubeSector pos, const uint8_t presence = UINT8_MAX);
void draw(cubeGroup pos, uint8_t presence = UINT8_MAX);

/**
* draw a tower and group of cubes around it
*
* @param pos which tower to print - see resources.hpp
* @param contents what color cube is inside, set Color::None for no cube
* @param contents what color cube is inside, set color::none for no cube
* @param presence a bitfield of present cubes. Starts with furthest and moves clockwise
* See the README for more information
*/
void drawTower(const TowerPos pos, const Color contents = Color::None, const uint8_t cubePresence = UINT8_MAX);
void draw(tower pos, color contents = color::none, uint8_t cubePresence = UINT8_MAX);

/**
* draw a scoring zone (and cubes inside)
*
* @param pos which zone to print
* @param contents what color cube is inside, set Color::None for no cube
* @param contents what color cube is inside, set color::none for no cube
* @param stackHeight how many cubes are in the zone vertically (puts number on top)
* See the README for more information
*/
void drawScoringZone(const ZonePos pos, const Color contents = Color::None, const uint8_t stackHeight = 0);
void draw(scoringZone pos, color contents = color::none, uint8_t stackHeight = 0);

/**
* draw a scoring zone (and cubes inside)
*
* @param pos which zone to print
* @param contents what colors of cubes are inside, use other function for 0 or 1 cubes
* @param stackHeight how many cubes are in the zone vertically (puts number on top)
* for both stacks
* for both stacks. See the README for more information
*/
void drawScoringZone(const ZonePos pos, const std::pair<Color,Color> contents, const std::pair<uint8_t,uint8_t> stackHeight);
void draw(scoringZone pos, std::pair<color, color> contents,
std::pair<uint8_t, uint8_t> stackHeight);

/**
* draw the four colored tiles
*
* called automatically by default
*/
void drawColoredTiles();
void drawcoloredTiles();

/**
* draw the zone lines
*
* called automatically by default
*/
void drawLines();

/**
* re-print the perimeter to make it look nice
*
* note: should be called after drawColoredTiles(), drawLines(), and drawScoringZone()s,
* but before drawtowers()s
* called automatically assuming you are drawing the whole field
* calling this manually is not advised
*
* note: should be called after drawcoloredTiles(), drawLines(), and draw()s,
* but before draw()s
*/
void reinforcePerimeter();

Expand All @@ -92,33 +164,40 @@ class Field{
* @param pos y-value of the midpoint of the robot
* note: there are 40 pixels for each field tile
*/
void drawRobot(const bool red, const uint8_t pos);
void drawRobot(bool red, uint8_t pos);

/**
* to be called after drawing all towers, cubes, and scoring zones
* this will automatically print all other game elements
*
* this is the suggested way to finish the field, as it will ensure everything is drawn in the
* correct order
*/
void finishDrawing();

private:
//Do not try and draw cubes youself, use the above functions
void drawCube(const std::pair<uint8_t, uint8_t> pos, const Color color, const uint8_t stackHeight, const bool targeted);
static void drawCube(lv_obj_t *parent, const std::pair<uint8_t, uint8_t> pos, const Color color, const uint8_t stackHeight, const bool targeted);
private:
// Cubes should be drawn automatically by the above functions
void drawCube(std::pair<uint8_t, uint8_t> pos, color color, uint8_t stackHeight, bool targeted);

static void drawCube(lv_obj_t *parent, std::pair<uint8_t, uint8_t> pos, color color,
uint8_t stackHeight, bool targeted);

void resetVectors();

const uint numOfBits[16] = {0,1,1,2,1,2,2,3,
1,2,2,3,2,3,3,4};
const uint numOfBits[16] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};

lv_obj_t *obj;

bool autoInit;

std::vector<CubeSector> cubesToDraw;
std::vector<TowerPos> towersToDraw;
std::vector<ZonePos> zonesToDraw;
bool wallDrawn;
std::pair<color, color> allianceTowerContents;

std::vector<cubeGroup> cubesToDraw;
std::vector<tower> towersToDraw;
std::vector<scoringZone> zonesToDraw;
};

}//namespace screen
} // namespace screen

#endif
Loading

0 comments on commit ab97496

Please sign in to comment.