Add more comments
This commit is contained in:
parent
26e48fd997
commit
b5a95218ea
25 changed files with 200 additions and 60 deletions
|
|
@ -22,7 +22,7 @@
|
|||
<ProgFlashFromRam>true</ProgFlashFromRam>
|
||||
<RamSnippetAddress>0x20000000</RamSnippetAddress>
|
||||
<UncachedRange />
|
||||
<preserveEEPROM>true</preserveEEPROM>
|
||||
<preserveEEPROM>false</preserveEEPROM>
|
||||
<OverrideVtorValue>exception_table</OverrideVtorValue>
|
||||
<BootSegment>2</BootSegment>
|
||||
<ResetRule>0</ResetRule>
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ void turnDisplayOnOff(bool shouldBeOn) {
|
|||
sendByteOnSPI(0x8D | shouldBeOn); // set charge pump on/off
|
||||
sendByteOnSPI(0x10 | shouldBeOn << 2); // set charge pump on/off
|
||||
sendByteOnSPI(0xAE | shouldBeOn); // turn display sleep on/off
|
||||
dataMode();
|
||||
}
|
||||
|
||||
void initializeDisplay(DrawFunction drawEverything) {
|
||||
|
|
|
|||
|
|
@ -7,30 +7,65 @@
|
|||
#include "../../util/rectangle/rectangle.h"
|
||||
|
||||
|
||||
/*
|
||||
SPI driver for D096-12864
|
||||
*/
|
||||
|
||||
#define DISPLAY_RESET_OUTPUT_PIN PB0
|
||||
#define DISPLAY_DC_OUTPUT_PIN PB4
|
||||
|
||||
// A two-times downscaling is used for greater performance
|
||||
#define DISPLAY_WIDTH_IN_PIXELS 64
|
||||
#define DISPLAY_HEIGHT_IN_PIXELS 32
|
||||
|
||||
// To easily access the window size
|
||||
#define WINDOW ((Rectangle){(Vec2){0, 0}, (Vec2){DISPLAY_WIDTH_IN_PIXELS, DISPLAY_HEIGHT_IN_PIXELS}})
|
||||
|
||||
// To conserve RAM, drawing is done in chunks of DEFAULT_COMPOSITING_WINDOW size
|
||||
// instead of buffering the whole display and writing it out at once
|
||||
#define DEFAULT_COMPOSITING_WINDOW ((Rectangle){(Vec2){0, 0}, (Vec2){DISPLAY_WIDTH_IN_PIXELS, 8}})
|
||||
|
||||
typedef void (*DrawFunction)(Rectangle);
|
||||
|
||||
// Call DrawFunction n times after a call to drawFrame has been made
|
||||
void initializeDisplay(DrawFunction drawEverything);
|
||||
|
||||
// Set a the brightness of the display
|
||||
// Value can be any number between 0 and 255.
|
||||
void setDisplayContrast(uint8_t value);
|
||||
|
||||
void turnDisplayOnOff(bool shouldBeOn);
|
||||
// To conserve program memory, pixel based intersection test
|
||||
// is implemented here.
|
||||
// Calling draw functions after calling startIntersectionTest
|
||||
// will set a wasIntersection bit appropriately.
|
||||
|
||||
// Clear buffer and wasIntersection bit
|
||||
void startIntersectionTest();
|
||||
|
||||
// Return wasIntersection bit
|
||||
bool endIntersectionTest();
|
||||
|
||||
// Initiate a draw sequence
|
||||
void drawFrame();
|
||||
void drawBitmapFromProgMem(Rectangle boundingBox, uint16_t const data[boundingBox.size.x][(boundingBox.size.y + 7) / 8], bool isMirrored);
|
||||
|
||||
// for white rectangle: invertedMask: don't care, fill: 0xFF
|
||||
// for black rectangle: invertedMask: 0xFF, fill: 0x00
|
||||
// Draw a sprite of size boundingBox.size at boundingBox.position from bitmap
|
||||
// if isMirrored then mirror around the vertical axis
|
||||
// Bitmap's data is interpreted the following way:
|
||||
/*
|
||||
Each 16 bit word corresponds to an 8 pixel high column.
|
||||
(These columns are laid out horizontally from left to right. Unfortunately,
|
||||
the display uses this addressing mode.) The higher 8 bits of the word is the
|
||||
an inverted mask and the lower 8 bits are the fill bits.
|
||||
newPixelColumn = oldPixelColumn & ~invertedMask | fill;
|
||||
|
||||
This seemingly weird layout is used to take advantage of SIMD operations
|
||||
and speed up the drawing process significantly.
|
||||
*/
|
||||
void drawBitmapFromProgMem(Rectangle boundingBox, uint16_t const bitmap[boundingBox.size.x][(boundingBox.size.y + 7) / 8], bool isMirrored);
|
||||
|
||||
// Draw a one byte repeated texture covering the parameter box
|
||||
// for a white rectangle use these arguments: invertedMask: don't care, fill: 0xFF
|
||||
// for a black rectangle use these arguments: invertedMask: 0xFF, fill: 0x00
|
||||
void drawFilledRectangle(Rectangle box, uint8_t invertedMask, uint8_t fill);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -5,13 +5,19 @@
|
|||
#include <avr/io.h>
|
||||
|
||||
|
||||
/*
|
||||
Custom NEC implementation using a TSOP4838
|
||||
*/
|
||||
|
||||
#define INFRA_ADDRESS 255
|
||||
#define IR_PIN PB3
|
||||
#define IR_PIN PB4
|
||||
#define REPEAT_CODE 1
|
||||
|
||||
typedef void (*OnCommandReceived)(uint8_t);
|
||||
typedef void (*OnReceiveStarted)();
|
||||
|
||||
void initializeInfra(OnCommandReceived onCommandReceived, OnReceiveStarted onReceiveStarted);
|
||||
// Initialize infra and call onCommandReceived with every received byte
|
||||
// Call onCommandReceived with the argument REPEAT_CODE if a repeat code
|
||||
// has been received.
|
||||
void initializeInfra(OnCommandReceived onCommandReceived);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -4,12 +4,10 @@
|
|||
#include <stdbool.h>
|
||||
#include <avr/io.h>
|
||||
|
||||
|
||||
// FrameFunction gets previousFrameTime (in milliseconds) as argument
|
||||
typedef bool (*FrameFunction)(uint8_t);
|
||||
|
||||
// frameFunction gets previousFrameTime (in milliseconds) as argument
|
||||
// Call function every frameLengthInMilliseconds while it returns true
|
||||
void startFrameLoop(FrameFunction function, uint8_t frameLengthInMilliseconds);
|
||||
|
||||
void powerOff();
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -12,22 +12,49 @@
|
|||
#include "output_pins/output_pins.h"
|
||||
|
||||
|
||||
/*
|
||||
This module contains the lowest level functions to manipulate the hardware.
|
||||
You only have to include this header file which serves as a facade.
|
||||
The sub-modules' implementation can be freely changed as long as they
|
||||
still implement these functions.
|
||||
*/
|
||||
|
||||
// Initialize every hardware element at once
|
||||
void initializeHardwareAccess();
|
||||
|
||||
// writing of unchanged byte is atomic
|
||||
// Write a single byte, when finished call the callback method
|
||||
// Writing of unchanged byte is atomic.
|
||||
bool asyncWriteEEPROM(uint8_t* buffer, OnEEPROMFinished onFinished);
|
||||
uint8_t loadSavedByteEEPROM(uint8_t address);
|
||||
|
||||
// Load byte from pointer
|
||||
uint8_t loadByteEEPROM(uint8_t* address);
|
||||
|
||||
// Load 2 bytes from pointer
|
||||
uint16_t loadWordEEPROM(uint16_t const* address);
|
||||
|
||||
// Load byte from address
|
||||
// It is different from loadByteEEPROM because
|
||||
// accepts a relative address instead of an
|
||||
// absolute one.
|
||||
uint8_t loadSavedByteEEPROM(uint8_t address);
|
||||
|
||||
// Enable the asynchronous writing of data from buffer
|
||||
void enableWritingEEPROM();
|
||||
void disableWritingEEPROM();
|
||||
|
||||
// Enable interrupt OCCRA for TIMER0 with a modulo of triggerInterruptInXTicks
|
||||
void enableTimerA(uint8_t triggerInterruptInXTicks);
|
||||
|
||||
// Enable interrupt OCCRB for TIMER0B with a modulo of triggerInterruptInXTicks
|
||||
void enableTimerB(uint8_t triggerInterruptInXTicks);
|
||||
void disableTimerB();
|
||||
|
||||
// Send a single byte on the built-in SPI interface
|
||||
// The transfer is done in a serial manner to achieve
|
||||
// greater throughput.
|
||||
void sendByteOnSPI(uint8_t byte);
|
||||
|
||||
// Set the value of an output pin
|
||||
void setOutputPin(uint8_t id, bool value);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
inline void initializePowerSaving() {
|
||||
setBit(ACSR, ACD); // disable ADC to save power
|
||||
PRR = BV(PRTIM1) | BV(PRADC); // disable power of timer1 and ADC
|
||||
PRR = BV(PRTIM1) | BV(PRADC); // disable power to timer1 and ADC
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -12,6 +12,4 @@ inline void initializeSPI() {
|
|||
DDRB |= BV(DO_PIN) | BV(USCK_PIN); // set pin directions for MOSI and SCK
|
||||
}
|
||||
|
||||
void sendByteOnSPI(uint8_t byte);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -4,9 +4,20 @@
|
|||
#include <avr/io.h>
|
||||
|
||||
|
||||
// Setup the drivers, and business layer objects and their relations
|
||||
// It is kind of a very basic dependency injection.
|
||||
void setupConnections();
|
||||
|
||||
// Start drawing frames and ticking objects
|
||||
void startGame();
|
||||
|
||||
// Make the machine go to sleep
|
||||
void handleOff();
|
||||
|
||||
// Increase or decrease the contrast (brightness) of the display
|
||||
// by the given value
|
||||
// The contrast can be any number between 0 and 255.
|
||||
// The function automatically clamps the contrast.
|
||||
void changeDisplayContrast(int8_t by);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ bool generateAstronautPredicate(Rectangle* proposedBoundingBox) {
|
|||
return (
|
||||
(
|
||||
(getCountOf(&Astronaut) == 1 && spaceshipObject->as.spaceship.progress >= hasHalfCrew) ||
|
||||
(getCountOf(&Astronaut) == 2 && spaceshipObject->as.spaceship.progress >= hasFullCrew)
|
||||
(getCountOf(&Astronaut) == 2 && spaceshipObject->as.spaceship.progress >= hasTable)
|
||||
) &&
|
||||
getIntersectingObjectOfType(*proposedBoundingBox, &Astronaut) == NULL &&
|
||||
isOnboard(*proposedBoundingBox)
|
||||
|
|
|
|||
|
|
@ -46,8 +46,7 @@ typedef enum {
|
|||
hasBeds = 2,
|
||||
hasTurret = 5,
|
||||
hasHalfCrew = 8,
|
||||
hasFullCrew = 15,
|
||||
hasTable = 25,
|
||||
hasTable = 15
|
||||
} Progress;
|
||||
|
||||
struct _spaceship_t {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue