-
Notifications
You must be signed in to change notification settings - Fork 0
/
gba.c
executable file
·95 lines (80 loc) · 2.42 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
/**
@file gba.c
@author Andrea Covre
@version 1.3 (March 22nd, 2020)
*/
#include "gba.h"
volatile unsigned short *videoBuffer = (volatile unsigned short *)0x6000000;
u32 vBlankCounter = 0;
void waitForVBlank(void) {
// preventing to count one VBlank more than once if the app is too fast
while(SCANLINECOUNTER > 160);
while(SCANLINECOUNTER < 160);
vBlankCounter++;
}
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) {
videoBuffer[OFFSET(row, col, WIDTH)] = color;
}
void drawRectDMA(int row, int col, int width, int height, volatile u16 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) {
for (int r = 0; r < 160; r++) {
DMA[3].src = &image[OFFSET(r, 0, 240)];
DMA[3].dst = &videoBuffer[OFFSET(r, 0, 240)];
DMA[3].cnt = 240 | DMA_ON;
}
}
void drawImageDMA(int row, int col, int width, int height, const u16 *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;
}
}
void fillScreenDMA(volatile u16 color) {
for (int r = 0; r < 160; r++) {
DMA[3].src = &color;
DMA[3].dst = &videoBuffer[OFFSET(r, 0, 240)];
DMA[3].cnt = 240 | 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);
}