Skip to content

Commit

Permalink
Added bilinear optimization, final fixes for 2.3 release
Browse files Browse the repository at this point in the history
  • Loading branch information
gtrxAC committed Dec 27, 2023
1 parent 989a11e commit 2635877
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 8 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# peanut.vxp
Game Boy emulator based on [Peanut-GB](https://github.com/deltabeard/Peanut-GB) for [MediaTek MRE](https://lpcwiki.miraheze.org/wiki/MAUI_Runtime_Environment) feature phones
Game Boy emulator based on [Peanut-GB](https://github.com/deltabeard/Peanut-GB) for [MediaTek MRE](https://lpcwiki.miraheze.org/wiki/MediaTek_MRE) feature phones

![](img/marioland_215.jpg)
*<div style="text-align:center;">Nokia 215 • Alcatel 3040g (thanks RedillGMV) • MyPhone T29 TV Duo (thanks aubykddi)</div>*

## Status
* Currently the emulator can run any Game Boy ROM that we've tested. The emulator core itself should support at least [these games](https://github.com/deltabeard/Peanut-GB/issues/31).
* Sound emulation is not implemented and not planned due to MRE limitations.
* Sound emulation is highly experimental and disabled by default.

## Compatibility
peanut.vxp currently works on any phone with MRE 2.5 or above, those mostly being Nokia and Alcatel phones released since around 2014. Support for older devices is planned but currently not possible.
Expand All @@ -18,6 +18,7 @@ peanut.vxp currently works on any phone with MRE 2.5 or above, those mostly bein
| MyPhone T29 TV Duo | Works
| Nokia 215<br>Nokia 230<br>Nokia 3310 2G (2017)<br>Likely other S30+ phones | Works
| Starmobile B506 | Works
| LG C299 | Stuck on MRE logo
| Alcatel A392CC | Crash
| Doro PhoneEasy 530X<br>Likely other Doro phones | Crash
| Logic M5 | Crash
Expand Down
52 changes: 46 additions & 6 deletions src/emu.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,10 @@ void lcd_draw_line_stub(struct gb_s *gb, const uint8_t pixels[160], const unsign
void write_save() {
if (!gb_inited) return;
int save_size = gb_get_save_size(gb);
if (save_size) {
write_from_addr_to_file(save_name, cart_ram, save_size);
log_write("Wrote save file");
}
if (save_size < 0 || !cart_ram) return;

write_from_addr_to_file(save_name, cart_ram, save_size);
log_write("Wrote save file");
}

// _____________________________________________________________________________
Expand Down Expand Up @@ -201,6 +201,41 @@ void scale_bilinear() {
scaled_interlace_count = !scaled_interlace_count;
}

// Grayscale version (only calculates red component, faster)
void scale_bilinear_gray() {
int begin = config->interlace ? scaled_interlace_count : 0;
int step = 1 + config->interlace;

for (int y = begin; y < 216; y += step) {
fixed_point y_position_FFF = y*1356;
int y_floor = F2I(y_position_FFF);

fixed_point y_fraction_FFF = y_position_FFF - I2F(y_floor);
fixed_point y_flip_fraction = 2048 - y_fraction_FFF;

for (int x = 0; x < 240; x++) {
fixed_point x_position_FFF = x*1356;
int x_floor = F2I(x_position_FFF);
fixed_point x_fraction_FFF = x_position_FFF - I2F(x_floor);

int index = y_floor * 160 + x_floor;
VMUINT16 pixel_tl = ((VMUINT16 *)scale_buf)[index];
VMUINT16 pixel_tr = ((VMUINT16 *)scale_buf)[index + 1];
VMUINT16 pixel_bl = ((VMUINT16 *)scale_buf)[index + 160];
VMUINT16 pixel_br = ((VMUINT16 *)scale_buf)[index + 161];

int interp_r = (FIXMUL(FIXMUL(2048 - x_fraction_FFF, y_flip_fraction), pixel_tl) +
FIXMUL(FIXMUL(x_fraction_FFF, y_flip_fraction), pixel_tr) +
FIXMUL(FIXMUL(2048 - x_fraction_FFF, y_fraction_FFF), pixel_bl) +
FIXMUL(FIXMUL(x_fraction_FFF, y_fraction_FFF), pixel_br));

((VMUINT16 *)canvas_buf)[y * 240 + x] = (interp_r & VM_COLOR_RED) | ((interp_r >> 5) & VM_COLOR_GREEN) | (interp_r >> 11);
}
}

scaled_interlace_count = !scaled_interlace_count;
}

// Nearest neighbor version
void scale_nearest() {
int begin = config->interlace ? scaled_interlace_count : 0;
Expand All @@ -214,7 +249,7 @@ void scale_nearest() {

scaled_interlace_count = !scaled_interlace_count;
}
extern int midi_handle;

void draw_emu() {
if (config->show_fps) tick_count = vm_get_tick_count();

Expand All @@ -230,7 +265,12 @@ void draw_emu() {
}

if (config->scale == SCALE_1_5X_NEAREST) scale_nearest();
else if (config->scale == SCALE_1_5X_BILINEAR) scale_bilinear();
else if (config->scale == SCALE_1_5X_BILINEAR) {
// If using the grayscale palette and not in GBC mode, use a faster algorithm
if (config->palette_choice == 0 && !gb->cgb.cgbMode) scale_bilinear_gray();
else scale_bilinear();
}

vm_graphic_flush_layer(layer_hdl, 2);
if (config->audio) audio_update();

Expand Down

0 comments on commit 2635877

Please sign in to comment.