-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgba.c
122 lines (101 loc) · 2.91 KB
/
gba.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include "gba.h"
volatile unsigned short *videoBuffer = (volatile unsigned short *) 0x6000000;
u32 vBlankCounter = 0;
void waitForVBlank(void) {
// TODO: IMPLEMENT
while(SCANLINECOUNTER > 160);
while(SCANLINECOUNTER < 160);
vBlankCounter++;
// (1)
// Write a while loop that loops until we're NOT in vBlank anymore:
// (This prevents counting one VBlank more than once if your app is too fast)
// (2)
// Write a while loop that keeps going until we're in vBlank:
// (3)
// Finally, increment the vBlank counter:
}
static int __qran_seed = 42;
static int qran(void) {
__qran_seed = 1664525 * __qran_seed + 1013904223;
return (__qran_seed >> 16) & 0x7FFF;
}
int randint(int min, int max) { return (qran() * (max - min) >> 15) + min; }
void setPixel(int row, int col, u16 color) {
// TODO: IMPLEMENT
UNUSED(row);
UNUSED(col);
UNUSED(color);
videoBuffer[OFFSET(row, col, WIDTH)] = color;
}
void drawRectDMA(int row, int col, int width, int height, volatile u16 color) {
// TODO: IMPLEMENT
UNUSED(row);
UNUSED(col);
UNUSED(width);
UNUSED(height);
UNUSED(color);
for (int r = 0; r < height; r++) {
DMA[3].src = &color;
DMA[3].dst = &videoBuffer[OFFSET(row + r, col, 240)];
DMA[3].cnt = width | DMA_ON | DMA_SOURCE_FIXED;
}
}
void drawFullScreenImageDMA(const u16 *image) {
// TODO: IMPLEMENT
UNUSED(image);
for (int r = 0; r < HEIGHT; r++) {
DMA[3].src = &image[OFFSET(r, 0, WIDTH)];
DMA[3].dst = &videoBuffer[OFFSET(r, 0, WIDTH)];
DMA[3].cnt = WIDTH | DMA_ON | DMA_SOURCE_INCREMENT | DMA_DESTINATION_INCREMENT;
}
}
void drawImageDMA(int row, int col, int width, int height, const u16 *image) {
// TODO: IMPLEMENT
UNUSED(row);
UNUSED(col);
UNUSED(width);
UNUSED(height);
UNUSED(image);
for (int r = 0; r < height; r++) {
DMA[3].src = &image[OFFSET(r, 0, width)];
DMA[3].dst = &videoBuffer[OFFSET(row + r, col, 240)];
DMA[3].cnt = width | DMA_ON | DMA_SOURCE_INCREMENT | DMA_DESTINATION_INCREMENT;
}
}
void fillScreenDMA(volatile u16 color) {
// TODO: IMPLEMENT
UNUSED(color);
for (int r = 0; r < HEIGHT; r++) {
DMA[3].src = &color;
DMA[3].dst = &videoBuffer[OFFSET(r, 0, WIDTH)];
DMA[3].cnt = WIDTH | DMA_ON | DMA_SOURCE_FIXED;
}
}
void drawChar(int row, int col, char ch, u16 color) {
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 8; j++) {
if (fontdata_6x8[OFFSET(j, i, 6) + ch * 48]) {
setPixel(row + j, col + i, color);
}
}
}
}
void drawString(int row, int col, char *str, u16 color) {
while (*str) {
drawChar(row, col, *str++, color);
col += 6;
}
}
void drawCenteredString(int row, int col, int width, int height, char *str, u16 color) {
u32 len = 0;
char *strCpy = str;
while (*strCpy) {
len++;
strCpy++;
}
u32 strWidth = 6 * len;
u32 strHeight = 8;
int new_row = row + ((height - strHeight) >> 1);
int new_col = col + ((width - strWidth) >> 1);
drawString(new_row, new_col, str, color);
}