Skip to content

Commit

Permalink
Add second screen mirror code
Browse files Browse the repository at this point in the history
  • Loading branch information
Lorenzooone committed Apr 1, 2024
1 parent 87c3096 commit bc6ece5
Show file tree
Hide file tree
Showing 16 changed files with 614 additions and 62 deletions.
11 changes: 11 additions & 0 deletions gba/src/4bcanvas.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,17 @@ const TileCanvas screen = {
.mapBase = se_mat
};

#ifdef __NDS__
const TileCanvas screen_sub = {
.left = 0, .top = 0, .width = SCREEN_WIDTH >> 3, .height = SCREEN_HEIGHT >> 3,
.chrBase = tile_mem_sub[0][0].data,
.map = 23,
.core = 0,
.mapTileBase = 0,
.mapBase = se_mat_sub
};
#endif

static
void fillcol(u32 *dst, unsigned int colStride,
unsigned int l, unsigned int t,
Expand Down
3 changes: 3 additions & 0 deletions gba/src/4bcanvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ typedef struct TileCanvas {
} TileCanvas;

extern const TileCanvas screen;
#ifdef __NDS__
extern const TileCanvas screen_sub;
#endif

void canvasClear(const TileCanvas *src, unsigned int color);
void canvasInit(const TileCanvas *src, unsigned int color);
Expand Down
9 changes: 9 additions & 0 deletions gba/src/audiosync.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,15 @@ void activity_audio_sync() {
pal_bg_mem[i] = progress >= min_progress[i] ? RGB5(31, 31, 31) : RGB5(0, 0, 0);
}
pal_obj_mem[1] = RGB5(31, 31, 31);
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
REG_DISPCNT_SUB = DCNT_MODE0 | DCNT_BG0 | DCNT_OBJ_1D | DCNT_OBJ | TILE_1D_MAP | ACTIVATE_SCREEN_HW;
REG_BGCNT_SUB[0] = BG_4BPP|BG_SIZE0|BG_CBB(0)|BG_SBB(PFMAP);
REG_BG_OFS_SUB[0].x = REG_BG_OFS_SUB[0].y = 0;
for (unsigned int i = 0; i < 6; ++i) {
pal_bg_mem_sub[i] = progress >= min_progress[i] ? RGB5(31, 31, 31) : RGB5(0, 0, 0);
}
pal_obj_mem_sub[1] = RGB5(31, 31, 31);
#endif
ppu_copy_oam();

if (progress == 120) {
Expand Down
7 changes: 7 additions & 0 deletions gba/src/backlight.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,14 @@ void activity_backlight_zone(void) {
VBlankIntrWait();
pal_bg_mem[0] = inverted ? RGB5(31, 31, 31) : RGB5(0, 0, 0);
pal_obj_mem[1] = inverted ? RGB5(0, 0, 0): RGB5(31, 31, 31);
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
pal_bg_mem_sub[0] = inverted ? RGB5(31, 31, 31) : RGB5(0, 0, 0);
pal_obj_mem_sub[1] = inverted ? RGB5(0, 0, 0): RGB5(31, 31, 31);
#endif
ppu_copy_oam();
REG_DISPCNT = DCNT_MODE0 | DCNT_OBJ | TILE_1D_MAP | ACTIVATE_SCREEN_HW;
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
REG_DISPCNT_SUB = DCNT_MODE0 | DCNT_OBJ | TILE_1D_MAP | ACTIVATE_SCREEN_HW;
#endif
}
}
52 changes: 44 additions & 8 deletions gba/src/help.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,16 @@ static void load_help_bg(void) {
memset16(tile_mem[3][0].data, 0x1111 * FG_BGCOLOR, 16*WINDOW_WIDTH*(PAGE_MAX_USABLE_LINES + 2));

load_bg_to_map(se_mat);
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
// Load pattern table
LZ77UnCompVram(helpbgtiles_chrTiles, tile_mem_sub[3][TILE_DECOMPRESSED_BASE].data);
LZ77UnCompVram(helpsprites_chrTiles, tile_mem_obj_sub[0][CHARACTER_VRAM_BASE].data);

// Clear VWF canvas
memset16(tile_mem_sub[3][0].data, 0x1111 * FG_BGCOLOR, 16*WINDOW_WIDTH*(PAGE_MAX_USABLE_LINES + 2));

load_bg_to_map(se_mat_sub);
#endif

help_bg_loaded = 1;
help_height = 0;
Expand Down Expand Up @@ -192,10 +202,10 @@ static void help_draw_cursor(unsigned int objx) {
oam_used = ou + 1;
}

static void help_draw_page(helpdoc_kind doc_num, unsigned int left, unsigned int keymask) {
static int help_draw_page(helpdoc_kind doc_num, unsigned int left, unsigned int keymask, TILE* target_tile_mem) {
// Draw document title
memset16(tile_mem[3][0].data, FG_BGCOLOR*0x1111, WINDOW_WIDTH * 16);
vwf8Puts(tile_mem[3][0].data, helptitles[doc_num], 0, FG_FGCOLOR);
memset16(target_tile_mem[0].data, FG_BGCOLOR*0x1111, WINDOW_WIDTH * 16);
vwf8Puts(target_tile_mem[0].data, helptitles[doc_num], 0, FG_FGCOLOR);

// Look up the address of the start of this page's text
help_cur_page = help_wanted_page;
Expand All @@ -204,7 +214,7 @@ static void help_draw_page(helpdoc_kind doc_num, unsigned int left, unsigned int

// Draw lines of text to the screen
while (y < PAGE_FINAL_MAX_LINES) {
u32 *dst = tile_mem[3][(y + 1)*WINDOW_WIDTH].data;
u32 *dst = target_tile_mem[(y + 1)*WINDOW_WIDTH].data;
++y;
memset16(dst, FG_BGCOLOR*0x1111, WINDOW_WIDTH * 16);
src = vwf8Puts(dst, src, left, FG_FGCOLOR);
Expand All @@ -216,19 +226,18 @@ static void help_draw_page(helpdoc_kind doc_num, unsigned int left, unsigned int

// Clear unused lines that had been used
for (unsigned int clear_y = y; clear_y < help_height; ++clear_y) {
u32 *dst = tile_mem[3][(clear_y + 1)*WINDOW_WIDTH].data;
u32 *dst = target_tile_mem[(clear_y + 1)*WINDOW_WIDTH].data;
memset16(dst, FG_BGCOLOR*0x1111, WINDOW_WIDTH * 16);
}

// Save how many lines are used and move the cursor up if needed
help_height = y;
if (help_cursor_y >= y) {
help_cursor_y = y - 1;
}

// Draw status line depending on size of document and which
// keys are enabled
u32 *dst = tile_mem[3][(PAGE_MAX_USABLE_LINES + 1)*WINDOW_WIDTH].data;
u32 *dst = target_tile_mem[(PAGE_MAX_USABLE_LINES + 1)*WINDOW_WIDTH].data;
memset16(dst, FG_BGCOLOR*0x1111, WINDOW_WIDTH * 16);

if (help_cumul_pages[doc_num + 1] - help_cumul_pages[doc_num] > 1) {
Expand All @@ -243,6 +252,8 @@ static void help_draw_page(helpdoc_kind doc_num, unsigned int left, unsigned int
if (keymask & KEY_B) {
vwf8Puts(dst, "B: Exit", WINDOW_WIDTH * 8 - 28, FG_FGCOLOR);
}

return y;
}

static const unsigned short bg0_x_sequence[] = {
Expand Down Expand Up @@ -298,8 +309,14 @@ unsigned int helpscreen(helpdoc_kind doc_num, unsigned int keymask) {
// If the help VRAM needs to be reloaded, reload its tiles and map
if (!help_bg_loaded) {
REG_DISPCNT = DCNT_BLANK | ACTIVATE_SCREEN_HW;
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
REG_DISPCNT_SUB = DCNT_BLANK | ACTIVATE_SCREEN_HW;
#endif
load_help_bg();
REG_DISPCNT = ACTIVATE_SCREEN_HW;
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
REG_DISPCNT_SUB = ACTIVATE_SCREEN_HW;
#endif
} else {
// If changing pages while BG CHR and map are loaded,
// schedule an out-load-in sequence and hide the cursor
Expand All @@ -322,6 +339,17 @@ unsigned int helpscreen(helpdoc_kind doc_num, unsigned int keymask) {
REG_BG_OFS[1].x = REG_BG_OFS[1].y = 0;
REG_BG_OFS[0].x = help_wnd_progress ? WXBASE : 256;
REG_BG_OFS[0].y = 4;
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
tonccpy(pal_bg_mem_sub+0x00, helpbgtiles_chrPal, sizeof(helpbgtiles_chrPal));
tonccpy(pal_obj_mem_sub+0x00, helpsprites_chrPal, sizeof(helpsprites_chrPal));

// Set up background regs (except DISPCNT)
REG_BGCNT_SUB[1] = BG_4BPP|BG_SIZE0|BG_CBB(3)|BG_SBB(BGMAP);
REG_BGCNT_SUB[0] = BG_4BPP|BG_SIZE1|BG_CBB(3)|BG_SBB(FGMAP);
REG_BG_OFS_SUB[1].x = REG_BG_OFS_SUB[1].y = 0;
REG_BG_OFS_SUB[0].x = help_wnd_progress ? WXBASE : 256;
REG_BG_OFS_SUB[0].y = 4;
#endif

// Freeze
while (1) {
Expand Down Expand Up @@ -363,7 +391,11 @@ unsigned int helpscreen(helpdoc_kind doc_num, unsigned int keymask) {

if (help_wnd_progress == 0) {
help_show_cursor = (keymask & KEY_UP) ? 6 : 0;
help_draw_page(doc_num, help_show_cursor, keymask);
int final_y = help_draw_page(doc_num, help_show_cursor, keymask, &tile_mem[3][0]);
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
help_draw_page(doc_num, help_show_cursor, keymask, &tile_mem_sub[3][0]);
#endif
help_height = final_y;
}

unsigned int wx = help_move_window();
Expand All @@ -376,6 +408,10 @@ unsigned int helpscreen(helpdoc_kind doc_num, unsigned int keymask) {
VBlankIntrWait();
REG_DISPCNT = DCNT_MODE0 | DCNT_BG1 | DCNT_BG0 | DCNT_OBJ_1D | DCNT_OBJ | TILE_1D_MAP | ACTIVATE_SCREEN_HW;
REG_BG_OFS[0].x = wx;
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
REG_DISPCNT_SUB = DCNT_MODE0 | DCNT_BG1 | DCNT_BG0 | DCNT_OBJ_1D | DCNT_OBJ | TILE_1D_MAP | ACTIVATE_SCREEN_HW;
REG_BG_OFS_SUB[0].x = wx;
#endif
ppu_copy_oam();
}
}
Expand Down
28 changes: 27 additions & 1 deletion gba/src/megaton.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,22 @@ void activity_megaton() {
REG_SOUNDCNT_L = 0xFF77; // PSG vol/pan
REG_SOUND1CNT_L = 0x08; // no sweep
#endif

dma_memset16(se_mat[PFMAP], BLANK_TILE, 32*(SCREEN_HEIGHT>>3)*2);
vwfDrawLabelsPositionBased(megaton_labels, megaton_positions, PFMAP, 0x44);

megaton_draw_static_reticle(se_mat);
// Make space for results
dma_memset16(tile_mem[0][0x30].data, 0x0000, 32 * 2 * NUM_TRIALS);
loadMapRowMajor(&(se_mat[PFMAP][2][2]), 0x30, 2, NUM_TRIALS);
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
dma_memset16(se_mat_sub[PFMAP], BLANK_TILE, 32*(SCREEN_HEIGHT>>3)*2);

megaton_draw_static_reticle(se_mat_sub);
// Make space for results
dma_memset16(tile_mem_sub[0][0x30].data, 0x0000, 32 * 2 * NUM_TRIALS);
loadMapRowMajor(&(se_mat_sub[PFMAP][2][2]), 0x30, 2, NUM_TRIALS);
#endif
vwfDrawLabelsPositionBased(megaton_labels, megaton_positions, PFMAP, 0x44);

do {
read_pad_help_check(helpsect_timing_and_reflex_test);
Expand All @@ -160,6 +169,9 @@ void activity_megaton() {
unsigned int early = diff < 0;
unsigned int value = early ? -diff : diff;
megaton_print_values(tile_mem[0][0x30 + progress * 2].data, value, early);
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
megaton_print_values(tile_mem_sub[0][0x30 + progress * 2].data, value, early);
#endif
if (!early && value <= 25) lag[progress++] = value;
}
#ifdef __NDS__
Expand Down Expand Up @@ -216,9 +228,20 @@ void activity_megaton() {
pal_bg_mem[0] = (x == 128 && with_audio) ? RGB5(31, 31, 31) : RGB5(0, 0, 0);
pal_bg_mem[1] = pal_obj_mem[1] = RGB5(31, 31, 31);
pal_bg_mem[2] = RGB5(20, 25, 31);
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
REG_DISPCNT_SUB = DCNT_MODE0 | DCNT_BG0 | DCNT_OBJ_1D | DCNT_OBJ | TILE_1D_MAP | ACTIVATE_SCREEN_HW;
REG_BGCNT_SUB[0] = BG_4BPP|BG_SIZE0|BG_CBB(0)|BG_SBB(PFMAP);
REG_BG_OFS_SUB[0].x = REG_BG_OFS_SUB[0].y = 0;
pal_bg_mem_sub[0] = (x == 128 && with_audio) ? RGB5(31, 31, 31) : RGB5(0, 0, 0);
pal_bg_mem_sub[1] = pal_obj_mem_sub[1] = RGB5(31, 31, 31);
pal_bg_mem_sub[2] = RGB5(20, 25, 31);
#endif
ppu_copy_oam();

megaton_draw_variable_data(se_mat, y, dir, randomize, with_audio);
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
megaton_draw_variable_data(se_mat_sub, y, dir, randomize, with_audio);
#endif

// beep
#ifdef __NDS__
Expand All @@ -244,6 +267,9 @@ void activity_megaton() {

// Display average: First throw away all labels below Y=120
dma_memset16(se_mat[PFMAP][(SCREEN_HEIGHT - 40)>> 3], BLANK_TILE, 32*4*2);
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
dma_memset16(se_mat_sub[PFMAP][(SCREEN_HEIGHT - 40)>> 3], BLANK_TILE, 32*4*2);
#endif

unsigned int sum = 0;
for (unsigned int i = 0; i < NUM_TRIALS; ++i) {
Expand Down
14 changes: 14 additions & 0 deletions gba/src/motionblur.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ void activity_motion_blur() {
dma_memset16(se_mat[PFMAP], BLANK_TILE, 32*(SCREEN_HEIGHT >> 3)*2);
for (unsigned int y = MOTION_BLUR_START_Y; y < MOTION_BLUR_END_Y; ++y)
dma_memset16(se_mat[PFMAP][y] + (SCREEN_WIDTH >> 4) - ((MOTION_BLUR_END_Y-MOTION_BLUR_START_Y)/2), 0x0A, (MOTION_BLUR_END_Y-MOTION_BLUR_START_Y)*2);
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
dma_memset16(se_mat_sub[PFMAP], BLANK_TILE, 32*(SCREEN_HEIGHT >> 3)*2);
for (unsigned int y = MOTION_BLUR_START_Y; y < MOTION_BLUR_END_Y; ++y)
dma_memset16(se_mat_sub[PFMAP][y] + (SCREEN_WIDTH >> 4) - ((MOTION_BLUR_END_Y-MOTION_BLUR_START_Y)/2), 0x0A, (MOTION_BLUR_END_Y-MOTION_BLUR_START_Y)*2);
#endif
vwfDrawLabelsPositionBased(motion_blur_labels, motion_blur_positions, PFMAP, 0x20);

unsigned int y = 0;
Expand Down Expand Up @@ -139,5 +144,14 @@ void activity_motion_blur() {
}
draw_motion_blur_values(se_mat, y, params);
REG_DISPCNT = DCNT_MODE0 | DCNT_BG0 | ACTIVATE_SCREEN_HW;
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
REG_BGCNT_SUB[0] = BG_4BPP|BG_SIZE0|BG_CBB(0)|BG_SBB(PFMAP);
REG_BG_OFS_SUB[0].x = REG_BG_OFS_SUB[0].y = 0;
for (unsigned int i = 0; i < 4; ++i) {
pal_bg_mem_sub[i] = RGB5(1, 1, 1) * bgc1[i];
}
draw_motion_blur_values(se_mat_sub, y, params);
REG_DISPCNT_SUB = DCNT_MODE0 | DCNT_BG0 | ACTIVATE_SCREEN_HW;
#endif
} while (!(new_keys & KEY_B));
}
49 changes: 46 additions & 3 deletions gba/src/overscan.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@ void activity_overscan() {
*c |= 0x44444444;
}
dma_memset16(se_mat[PFMAP], 0x0004, 32*(SCREEN_HEIGHT >> 3)*2);
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
// Make all BG tiles opaque
for (u32 *c = tile_mem_sub[0][0].data; c < tile_mem_sub[0][32].data; ++c) {
*c |= 0x44444444;
}
dma_memset16(se_mat_sub[PFMAP], 0x0004, 32*(SCREEN_HEIGHT >> 3)*2);
#endif

while (1) {
read_pad_help_check(helpsect_overscan);
Expand Down Expand Up @@ -119,10 +126,19 @@ void activity_overscan() {
}
REG_BGCNT[0] = BG_4BPP|BG_SIZE0|BG_CBB(0)|BG_SBB(PFMAP);
REG_BG_OFS[0].x = REG_BG_OFS[0].y = 0;
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
// Color 0: outside
pal_bg_mem_sub[0] = pal_bg_mem_sub[5] = inverted ? RGB5(0, 0, 0) : RGB5(31, 31, 31);
pal_bg_mem_sub[4] = inverted ? RGB5(23, 23, 23) : RGB5(15, 15, 15);
if (cur_keys & KEY_A) {
pal_obj_mem_sub[2] = inverted ? RGB5(31, 31, 31) : RGB5(0, 0, 0);
} else {
pal_obj_mem_sub[2] = inverted ? RGB5(15, 15, 15) : RGB5(23, 23, 23);
}
REG_BGCNT_SUB[0] = BG_4BPP|BG_SIZE0|BG_CBB(0)|BG_SBB(PFMAP);
REG_BG_OFS_SUB[0].x = REG_BG_OFS_SUB[0].y = 0;
#endif
ppu_copy_oam();
REG_DISPCNT = DCNT_MODE0 | DCNT_BG0 | DCNT_OBJ_1D | DCNT_OBJ | DCNT_WIN0 | DCNT_WIN1 | TILE_1D_MAP | ACTIVATE_SCREEN_HW;
REG_WINOUT = 0x10; // BG0 inside, BG1 outside
REG_WININ = 0x1111;

// start<<8 | end
// Do this with the y value to fix an NDS bug.
Expand All @@ -131,6 +147,10 @@ void activity_overscan() {
unsigned int y_set_value = (7 << 8) | ((SCREEN_HEIGHT - dist[3]) & 0xFF);
if(dist[2] == 0)
y_set_value = ((SCREEN_HEIGHT - dist[3]) & 0xFF);

REG_DISPCNT = DCNT_MODE0 | DCNT_BG0 | DCNT_OBJ_1D | DCNT_OBJ | DCNT_WIN0 | DCNT_WIN1 | TILE_1D_MAP | ACTIVATE_SCREEN_HW;
REG_WINOUT = 0x10; // BG0 inside, BG1 outside
REG_WININ = 0x1111;

REG_WIN0H = (dist[1] << 8) | (SCREEN_WIDTH / 2);
REG_WIN0V = y_set_value;
Expand All @@ -147,6 +167,23 @@ void activity_overscan() {
#endif
REG_DMA0DAD = (intptr_t)&(REG_WIN0V);
REG_DMA0CNT = 1|DMA_DST_FIXED|DMA_SRC_FIXED|DMA_32|DMA_AT_HBLANK|DMA_ENABLE;

#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
REG_DISPCNT_SUB = DCNT_MODE0 | DCNT_BG0 | DCNT_OBJ_1D | DCNT_OBJ | DCNT_WIN0 | DCNT_WIN1 | TILE_1D_MAP | ACTIVATE_SCREEN_HW;
REG_WINOUT_SUB = 0x10; // BG0 inside, BG1 outside
REG_WININ_SUB = 0x1111;

REG_WIN0H_SUB = (dist[1] << 8) | (SCREEN_WIDTH / 2);
REG_WIN0V_SUB = y_set_value;
// NDS requires two windows to fill 256 pixels on the X axys
REG_WIN1H_SUB = ((SCREEN_WIDTH / 2) << 8) | ((SCREEN_WIDTH - dist[0]) & 0xFF);
REG_WIN1V_SUB = y_set_value;

REG_DMA1CNT = 0;
REG_DMA1SAD = (intptr_t)&(DMA_FILL(0));
REG_DMA1DAD = (intptr_t)&(REG_WIN0V_SUB);
REG_DMA1CNT = 1|DMA_DST_FIXED|DMA_SRC_FIXED|DMA_32|DMA_AT_HBLANK|DMA_ENABLE;
#endif

for (int i = 0; i < 4; ++i) {
unsigned int x = overscan_dist_x[i];
Expand All @@ -157,6 +194,12 @@ void activity_overscan() {
se_mat[PFMAP][y][x + 1] = 0x0010 + (value - tens * 10);
se_mat[PFMAP][y + 1][x] = 0x0006;
se_mat[PFMAP][y + 1][x + 1] = 0x0007;
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
se_mat_sub[PFMAP][y][x] = tens ? (0x0010 + tens) : 0x0004;
se_mat_sub[PFMAP][y][x + 1] = 0x0010 + (value - tens * 10);
se_mat_sub[PFMAP][y + 1][x] = 0x0006;
se_mat_sub[PFMAP][y + 1][x + 1] = 0x0007;
#endif
}
}

Expand Down
Loading

0 comments on commit bc6ece5

Please sign in to comment.