Skip to content

Commit 3d2c9d0

Browse files
committed
GBA: finish manual lag test
By now, I have added all tests except these five: Shadow sprite, Stopwatch, Scroll test (Hill zone and Vertical), and the PCM feature of Sound test. If I fit them in 31K (6.2K each), I fit the whole suite in 64K. Otherwise I have to go compressing stuff. But it looks like I can release what I have so far to early access.
1 parent ce748fc commit 3d2c9d0

File tree

5 files changed

+181
-25
lines changed

5 files changed

+181
-25
lines changed

gba/CHANGES.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
0.01 (2018-06-xx)
2-
* initial release, with everything but Shadow sprite, Stopwatch,
3-
Manual lag, Hill zone scroll, Vertical scroll, and PCM audio test
1+
0.01 (2018-06-19)
2+
* initial release, with all tests except Shadow sprite, Stopwatch,
3+
Hill zone scroll, Vertical scroll, and PCM in audio test

gba/src/global.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ void ppu_clear_oam(size_t start);
8989
void ppu_copy_oam(void);
9090
void dma_memset16(void *s, unsigned int c, size_t n);
9191

92+
// rand.c
93+
void lcg_srand(unsigned int in_seed);
94+
int lcg_rand(void);
95+
#define LCG_RAND_MAX 65535
96+
9297
// vwfdraw.c
9398
void loadMapRowMajor(unsigned short *dst, unsigned int tilenum,
9499
unsigned int width, unsigned int height);

gba/src/helppages.txt

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Overscan
1515
----
1616
(NYA) Shadow sprite
1717
(NYA) Stopwatch
18-
(WIP) Manual lag test
18+
Manual lag test
1919
(NYA) Hill zone scroll
2020
(NYA) Vertical scroll
2121
Grid scroll
@@ -587,13 +587,11 @@ Select: Show or hide
587587

588588
== 160p Test Suite ==
589589

590-
Ver. 0.00
590+
Version 0.01 (2018-06-19)
591591
We're just getting started
592592

593-
© 2011-2016
594-
Artemio Urbina
595-
© 2015-2018
596-
Damian Yerrick
593+
© 2011-2016 Artemio Urbina
594+
© 2015-2018 Damian Yerrick
597595
This is free software; see
598596
the source for copying
599597
conditions. The program
@@ -627,16 +625,15 @@ You can help:
627625
Roadmap
628626

629627
0.02: Stopwatch
630-
0.03: Manual lag test
631-
0.04: Scroll test
632-
0.05: Shadow sprite
633-
0.06: PCM in Sound test
634-
0.07: Compress under 64 KiB
628+
0.03: Scroll test
629+
0.04: Shadow sprite
630+
0.05: PCM in Sound test
631+
0.06: Compress under 64 KiB
635632
----
636633
Size watch
637634

638-
As of 0.01, all but 5 tests
639-
fit in 32 KiB, but some of the
635+
As of 0.01, all but 4 tests
636+
fit in 33 KiB, but some of the
640637
remaining tests are the most
641638
asset-intensive.
642639
Should they bust my 64 KiB

gba/src/megaton.c

Lines changed: 148 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,21 @@
22
#include <gba_input.h>
33
#include <gba_sound.h>
44
#include <gba_video.h>
5+
#include "posprintf.h"
56

67
extern const unsigned char helpsect_manual_lag_test[];
78
#define PFMAP 23
8-
#define NUM_PRESSES 10
9+
#define NUM_TRIALS 10
910
#define BLANK_TILE 0x0004
11+
#define ARROW_TILE 0x0005
12+
#define CHECKED_TILE 0x0027
13+
#define UNCHECKED_TILE 0x0026
14+
#define RETICLE_TILE 0x0028
15+
#define WORD_OFF 0x0044
16+
#define WORD_ON 0x0046
1017

1118
// The "On" and "Off" labels must come first because they cause
12-
// text to be allocated with off at 0x0030 and on at 0x0032
19+
// text to be allocated with off and on at WORD_OFF and WORD_ON
1320
static const char megaton_labels[] =
1421
"\x83""\x88""off\n"
1522
"\x84""\x90""on\n"
@@ -20,11 +27,39 @@ static const char megaton_labels[] =
2027
"\x44""\x88""Randomize\n"
2128
"\x44""\x90""Audio";
2229

30+
static void megaton_draw_boolean(unsigned int y, unsigned int value) {
31+
MAP[PFMAP][y][15] = value ? CHECKED_TILE : UNCHECKED_TILE;
32+
unsigned int onoff = value ? WORD_ON : WORD_OFF;
33+
MAP[PFMAP][y][16] = onoff;
34+
MAP[PFMAP][y][17] = onoff + 1;
35+
}
36+
37+
static void megaton_draw_reticle(unsigned int x, unsigned int y) {
38+
unsigned int i = oam_used;
39+
y = OBJ_Y(y) | OBJ_16_COLOR | ATTR0_SQUARE;
40+
x = OBJ_X(x) | ATTR1_SIZE_16;
41+
42+
SOAM[i].attr0 = y;
43+
SOAM[i].attr1 = x;
44+
SOAM[i++].attr2 = RETICLE_TILE;
45+
SOAM[i].attr0 = y;
46+
SOAM[i].attr1 = x + 16 + OBJ_HFLIP;
47+
SOAM[i++].attr2 = RETICLE_TILE;
48+
y += 16;
49+
SOAM[i].attr0 = y;
50+
SOAM[i].attr1 = x + OBJ_VFLIP;
51+
SOAM[i++].attr2 = RETICLE_TILE;
52+
SOAM[i].attr0 = y;
53+
SOAM[i].attr1 = x + 16 + OBJ_HFLIP + OBJ_VFLIP;
54+
SOAM[i++].attr2 = RETICLE_TILE;
55+
oam_used = i;
56+
}
57+
2358
void activity_megaton() {
24-
signed char lag[NUM_PRESSES] = {-1};
59+
signed char lag[NUM_TRIALS] = {-1};
2560
unsigned int x = 129, xtarget = 160;
2661
unsigned int with_audio = 1, dir = 1, randomize = 1;
27-
unsigned int progress = 0;
62+
unsigned int progress = 0, y = 0;
2863

2964
load_common_bg_tiles();
3065
load_common_obj_tiles();
@@ -34,17 +69,84 @@ void activity_megaton() {
3469
REG_SOUNDCNT_L = 0xFF77; // PSG vol/pan
3570
REG_SOUND1CNT_L = 0x08; // no sweep
3671
dma_memset16(MAP[PFMAP], BLANK_TILE, 32*20*2);
37-
vwfDrawLabels(megaton_labels, PFMAP, 0x30);
72+
vwfDrawLabels(megaton_labels, PFMAP, 0x44);
73+
74+
// Draw stationary reticle
75+
for (unsigned int y = 0; y < 2; ++y) {
76+
for (unsigned int x = 0; x < 2; ++x) {
77+
unsigned int t = 0x0028 + y * 2 + x;
78+
MAP[PFMAP][7+y][13+x] = t;
79+
MAP[PFMAP][7+y][16-x] = t ^ 0x400;
80+
MAP[PFMAP][10-y][13+x] = t ^ 0x800;
81+
MAP[PFMAP][10-y][16-x] = t ^ 0xC00;
82+
}
83+
}
84+
85+
// Make space for results
86+
dma_memset16(PATRAM4(0, 0x30), 0x0000, 32 * 20);
87+
loadMapRowMajor(&(MAP[PFMAP][2][2]), 0x30, 2, 10);
3888

3989
do {
4090
read_pad_help_check(helpsect_manual_lag_test);
4191

42-
if (new_keys && KEY_B) {
92+
if (new_keys & KEY_B) {
4393
break;
4494
}
95+
if (new_keys & KEY_A) {
96+
signed int diff = x - 128;
97+
if (xtarget < 128) diff = -diff;
98+
unsigned int early = diff < 0;
99+
unsigned int value = early ? -diff : diff;
100+
uint32_t *tileaddr = PATRAM4(0, 0x30 + progress * 2);
101+
dma_memset16(tileaddr, 0x0000, 32 * 2);
102+
if (early) {
103+
vwf8PutTile(tileaddr, 'E', 0, 1);
104+
}
105+
unsigned int tens = value / 10;
106+
if (tens) {
107+
vwf8PutTile(tileaddr, tens + '0', 6, 1);
108+
}
109+
vwf8PutTile(tileaddr, (value - tens * 10) + '0', 11, 1);
110+
if (!early && value <= 25) lag[progress++] = value;
111+
}
112+
REG_SOUND2CNT_L = ((new_keys & KEY_A) && with_audio) ? 0xA080 : 0x0000;
113+
REG_SOUND2CNT_H = (2048 - 262) | 0x8000;
114+
if ((new_keys & KEY_UP) && y > 0) {
115+
--y;
116+
}
117+
if ((new_keys & KEY_DOWN) && y < 2) {
118+
++y;
119+
}
120+
if (new_keys & (KEY_LEFT | KEY_RIGHT)) {
121+
switch (y) {
122+
case 0: // change direction
123+
dir += (new_keys & KEY_LEFT) ? 2 : 1;
124+
if (dir > 3) dir -= 3;
125+
break;
126+
case 1:
127+
randomize = !randomize;
128+
break;
129+
case 2:
130+
with_audio = !with_audio;
131+
break;
132+
}
133+
}
45134

135+
// Move reticle
136+
x += (xtarget > x) ? 1 : -1;
137+
if (x == xtarget) {
138+
xtarget = 36 + 128;
139+
if (randomize) xtarget += (lcg_rand() >> 12) - 8;
140+
if (x > 128) xtarget = 256 - xtarget;
141+
}
142+
46143
oam_used = 0;
47-
// Draw sprites
144+
if (dir & 0x01) {
145+
megaton_draw_reticle(104 + x - 128, 56);
146+
}
147+
if (dir & 0x02) {
148+
megaton_draw_reticle(104, 56 + x - 128);
149+
}
48150
ppu_clear_oam(oam_used);
49151

50152
VBlankIntrWait();
@@ -53,12 +155,49 @@ void activity_megaton() {
53155
BG_OFFSET[0].x = BG_OFFSET[0].y = 0;
54156
BG_COLORS[0] = (x == 128 && with_audio) ? RGB5(31, 31, 31) : RGB5(0, 0, 0);
55157
BG_COLORS[1] = OBJ_COLORS[1] = RGB5(31, 31, 31);
158+
BG_COLORS[2] = RGB5(20, 25, 31);
56159
ppu_copy_oam();
57160

58-
} while (!(new_keys & KEY_B));
161+
// Draw the cursor
162+
for (unsigned int i = 0; i < 3; ++i) {
163+
unsigned int tilenum = (i == y) ? ARROW_TILE : BLANK_TILE;
164+
MAP[PFMAP][i + 16][7] = tilenum;
165+
}
166+
MAP[PFMAP][16][15] = (dir & 0x01) ? CHECKED_TILE : UNCHECKED_TILE;
167+
MAP[PFMAP][16][19] = (dir & 0x02) ? CHECKED_TILE : UNCHECKED_TILE;
168+
megaton_draw_boolean(17, randomize);
169+
megaton_draw_boolean(18, with_audio);
170+
171+
// TODO: beep
172+
REG_SOUND1CNT_H = (x == 128 && with_audio) ? 0xA080 : 0x0000;
173+
REG_SOUND1CNT_X = (2048 - 131) | 0x8000;
174+
} while (!(new_keys & KEY_B) && (progress < NUM_TRIALS));
175+
59176
BG_COLORS[0] = RGB5(0, 0, 0);
60177
REG_SOUNDCNT_X = 0; // reset audio
178+
if (progress < 10) return;
179+
180+
// Display average: First throw away all labels below Y=120
181+
dma_memset16(MAP[PFMAP][15], BLANK_TILE, 32*4*2);
182+
183+
unsigned int sum = 0;
184+
for (unsigned int i = 0; i < NUM_TRIALS; ++i) {
185+
sum += lag[i];
186+
}
187+
unsigned int whole_frames = sum / NUM_TRIALS;
188+
posprintf(help_line_buffer, "\x40\x80""Average lag: %d.%d frames",
189+
whole_frames, sum - whole_frames * NUM_TRIALS);
190+
vwfDrawLabels(help_line_buffer, PFMAP, 0x44);
191+
192+
// Ignore spurious presses
193+
for (unsigned int i = 20; i > 0; --i) {
194+
VBlankIntrWait();
195+
}
61196

62-
if (new_keys && KEY_B) return;
197+
do {
198+
VBlankIntrWait();
199+
read_pad();
200+
} while (!new_keys);
63201

202+
// TODO: Display average lag
64203
}

gba/src/rand.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#include "global.h"
2+
3+
// This uses the same linear congruential generator as cc65's
4+
// random function, but with different tempering.
5+
6+
static unsigned int seed = 1;
7+
8+
void lcg_srand(unsigned int in_seed) {
9+
seed = in_seed;
10+
}
11+
12+
int lcg_rand(void) {
13+
seed = (seed * 0x01010101) + 0x31415927;
14+
return (seed ^ (seed >> 16)) & 0xFFFF;
15+
}

0 commit comments

Comments
 (0)