Add rotation to wxwidgets frontend
Add rotation to wxwidgets frontend, code derived from gtk frontend. rm: my changes are mostly cosmetics (how can you read multiple statements in one line? a mistery to me :) and some tidy up for gpu_screen_to_rgb. Let me left this quote in my defense: "If you want to go somewhere, goto is the best way to get there." Patch #4 by yar-tour from #2969484
This commit is contained in:
parent
59a8ea41ab
commit
fbe279dbdf
|
@ -36,6 +36,9 @@
|
||||||
#include "gdbstub.h"
|
#include "gdbstub.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define SCREEN_SIZE (256*192*3)
|
||||||
|
static int nds_screen_rotation_angle;
|
||||||
|
|
||||||
SoundInterface_struct *SNDCoreList[] = {
|
SoundInterface_struct *SNDCoreList[] = {
|
||||||
&SNDDummy,
|
&SNDDummy,
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
@ -169,30 +172,84 @@ public:
|
||||||
NDS_LoadROM(dialog.GetPath().mb_str(), dialog.GetPath().mb_str());
|
NDS_LoadROM(dialog.GetPath().mb_str(), dialog.GetPath().mb_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void gpu_screen_to_rgb(u8 *rgb1, u8 *rgb2)
|
||||||
//TODO should integrate filter system
|
{
|
||||||
void onPaint(wxPaintEvent &event)
|
u16 gpu_pixel;
|
||||||
{
|
u8 pixel[3];
|
||||||
wxPaintDC dc(this);
|
u8 *rgb = rgb1;
|
||||||
|
const int rot = nds_screen_rotation_angle;
|
||||||
int width = 256;
|
int done = false;
|
||||||
int height = 384;
|
int offset = 0;
|
||||||
|
|
||||||
u16 gpu_pixel;
|
loop:
|
||||||
u32 offset;
|
for (int i = 0; i < 256; i++) {
|
||||||
u8 rgb[256*384*3];
|
for (int j = 0; j < 192; j++) {
|
||||||
for (int i = 0; i < 256; i++) {
|
gpu_pixel = *((u16 *) & GPU_screen[(i + (j + offset) * 256) << 1]);
|
||||||
for (int j = 0; j < 384; j++) {
|
pixel[0] = ((gpu_pixel >> 0) & 0x1f) << 3;
|
||||||
gpu_pixel = *((u16 *) & GPU_screen[(i + j * 256) << 1]);
|
pixel[1] = ((gpu_pixel >> 5) & 0x1f) << 3;
|
||||||
offset = i * 3 + j * 3 * 256;
|
pixel[2] = ((gpu_pixel >> 10) & 0x1f) << 3;
|
||||||
*(rgb + offset + 0) = ((gpu_pixel >> 0) & 0x1f) << 3;
|
switch (rot) {
|
||||||
*(rgb + offset + 1) = ((gpu_pixel >> 5) & 0x1f) << 3;
|
case 0:
|
||||||
*(rgb + offset + 2) = ((gpu_pixel >> 10) & 0x1f) << 3;
|
memcpy(rgb+((i+j*256)*3),pixel,3);
|
||||||
}
|
break;
|
||||||
}
|
case 90:
|
||||||
|
memcpy(rgb+SCREEN_SIZE-((j+(255-i)*192)*3)-3,pixel,3);
|
||||||
wxBitmap m_bitmap(wxImage(width, height, rgb, true));
|
break;
|
||||||
dc.DrawBitmap(m_bitmap, 0, 0, true);
|
case 180:
|
||||||
|
memcpy(rgb+SCREEN_SIZE-((i+j*256)*3)-3,pixel,3);
|
||||||
|
break;
|
||||||
|
case 270:
|
||||||
|
memcpy(rgb+((j+(255-i)*192)*3),pixel,3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (done == false) {
|
||||||
|
offset = 192;
|
||||||
|
rgb = rgb2;
|
||||||
|
done = true;
|
||||||
|
goto loop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO should integrate filter system
|
||||||
|
void onPaint(wxPaintEvent &event)
|
||||||
|
{
|
||||||
|
u8 rgb1[SCREEN_SIZE], rgb2[SCREEN_SIZE];
|
||||||
|
wxPaintDC dc(this);
|
||||||
|
int w, h;
|
||||||
|
|
||||||
|
if (nds_screen_rotation_angle == 90 || nds_screen_rotation_angle == 270) {
|
||||||
|
w = 192;
|
||||||
|
h = 256;
|
||||||
|
} else {
|
||||||
|
w = 256;
|
||||||
|
h = 192;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpu_screen_to_rgb(rgb1, rgb2);
|
||||||
|
wxBitmap m_bitmap1(wxImage(w, h, rgb1, true));
|
||||||
|
wxBitmap m_bitmap2(wxImage(w, h, rgb2, true));
|
||||||
|
switch (nds_screen_rotation_angle) {
|
||||||
|
case 0:
|
||||||
|
dc.DrawBitmap(m_bitmap1, 0, 0, true);
|
||||||
|
dc.DrawBitmap(m_bitmap2, 0, 192, true);
|
||||||
|
break;
|
||||||
|
case 90:
|
||||||
|
dc.DrawBitmap(m_bitmap2, 0, 0, true);
|
||||||
|
dc.DrawBitmap(m_bitmap1, 192, 0, true);
|
||||||
|
break;
|
||||||
|
case 180:
|
||||||
|
dc.DrawBitmap(m_bitmap2, 0, 0, true);
|
||||||
|
dc.DrawBitmap(m_bitmap1, 0, 192, true);
|
||||||
|
break;
|
||||||
|
case 270:
|
||||||
|
dc.DrawBitmap(m_bitmap1, 0, 0, true);
|
||||||
|
dc.DrawBitmap(m_bitmap2, 192, 0, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void onIdle(wxIdleEvent &event){
|
void onIdle(wxIdleEvent &event){
|
||||||
|
@ -351,6 +408,7 @@ public:
|
||||||
void Menu_SaveStates(wxCommandEvent &event);
|
void Menu_SaveStates(wxCommandEvent &event);
|
||||||
void Menu_LoadStates(wxCommandEvent &event);
|
void Menu_LoadStates(wxCommandEvent &event);
|
||||||
void NDSInitialize();
|
void NDSInitialize();
|
||||||
|
void changeRotation(wxCommandEvent &event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef GDB_STUB
|
#ifdef GDB_STUB
|
||||||
|
@ -399,14 +457,33 @@ enum
|
||||||
wSaveScreenshotAs,
|
wSaveScreenshotAs,
|
||||||
wQuickScreenshot,
|
wQuickScreenshot,
|
||||||
wLuaWindow,
|
wLuaWindow,
|
||||||
|
wConfigureControls,
|
||||||
|
wRot0,
|
||||||
|
wRot90,
|
||||||
|
wRot180,
|
||||||
|
wRot270,
|
||||||
|
/* stupid enums: these two should be the at the end */
|
||||||
wLoadState01,
|
wLoadState01,
|
||||||
wSaveState01 = wLoadState01+20,
|
wSaveState01 = wLoadState01+20
|
||||||
wConfigureControls
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void DesmumeFrame::Menu_SaveStates(wxCommandEvent &event){savestate_slot(event.GetId() - wSaveState01);}
|
void DesmumeFrame::Menu_SaveStates(wxCommandEvent &event){savestate_slot(event.GetId() - wSaveState01);}
|
||||||
void DesmumeFrame::Menu_LoadStates(wxCommandEvent &event){loadstate_slot(event.GetId() - wLoadState01);}
|
void DesmumeFrame::Menu_LoadStates(wxCommandEvent &event){loadstate_slot(event.GetId() - wLoadState01);}
|
||||||
|
|
||||||
|
void DesmumeFrame::changeRotation(wxCommandEvent &event){
|
||||||
|
int rot = (event.GetId() - wRot0)*90;
|
||||||
|
|
||||||
|
if (rot == nds_screen_rotation_angle)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (rot == 90 || rot == 270) {
|
||||||
|
SetClientSize(384,256);
|
||||||
|
} else {
|
||||||
|
SetClientSize(256,384);
|
||||||
|
}
|
||||||
|
nds_screen_rotation_angle = rot;
|
||||||
|
}
|
||||||
|
|
||||||
BEGIN_EVENT_TABLE(DesmumeFrame, wxFrame)
|
BEGIN_EVENT_TABLE(DesmumeFrame, wxFrame)
|
||||||
EVT_PAINT(DesmumeFrame::onPaint)
|
EVT_PAINT(DesmumeFrame::onPaint)
|
||||||
EVT_IDLE(DesmumeFrame::onIdle)
|
EVT_IDLE(DesmumeFrame::onIdle)
|
||||||
|
@ -447,6 +524,8 @@ EVT_MENU(wCloseRom,DesmumeFrame::closeRom)
|
||||||
EVT_MENU(wImportBackupMemory,DesmumeFrame::importBackupMemory)
|
EVT_MENU(wImportBackupMemory,DesmumeFrame::importBackupMemory)
|
||||||
EVT_MENU(wExportBackupMemory,DesmumeFrame::exportBackupMemory)
|
EVT_MENU(wExportBackupMemory,DesmumeFrame::exportBackupMemory)
|
||||||
|
|
||||||
|
EVT_MENU_RANGE(wRot0,wRot270,DesmumeFrame::changeRotation)
|
||||||
|
|
||||||
EVT_MENU(wSaveScreenshotAs,DesmumeFrame::saveScreenshotAs)
|
EVT_MENU(wSaveScreenshotAs,DesmumeFrame::saveScreenshotAs)
|
||||||
EVT_MENU(wQuickScreenshot,DesmumeFrame::quickScreenshot)
|
EVT_MENU(wQuickScreenshot,DesmumeFrame::quickScreenshot)
|
||||||
|
|
||||||
|
@ -532,8 +611,6 @@ DesmumeFrame::DesmumeFrame(const wxString& title)
|
||||||
: wxFrame(NULL, wxID_ANY, title)
|
: wxFrame(NULL, wxID_ANY, title)
|
||||||
{
|
{
|
||||||
|
|
||||||
this->SetClientSize(256,384);
|
|
||||||
|
|
||||||
wxMenu *fileMenu = new wxMenu;
|
wxMenu *fileMenu = new wxMenu;
|
||||||
wxMenu *emulationMenu = new wxMenu;
|
wxMenu *emulationMenu = new wxMenu;
|
||||||
wxMenu *viewMenu = new wxMenu;
|
wxMenu *viewMenu = new wxMenu;
|
||||||
|
@ -568,6 +645,14 @@ DesmumeFrame::DesmumeFrame(const wxString& title)
|
||||||
emulationMenu->Append(wPause, _T("&Pause\tAlt-P"), _T("Pause Emulation"));
|
emulationMenu->Append(wPause, _T("&Pause\tAlt-P"), _T("Pause Emulation"));
|
||||||
emulationMenu->Append(wReset, _T("&Reset\tAlt-R"), _T("Reset Emulation"));
|
emulationMenu->Append(wReset, _T("&Reset\tAlt-R"), _T("Reset Emulation"));
|
||||||
|
|
||||||
|
wxMenu *rotateMenu = new wxMenu;
|
||||||
|
{
|
||||||
|
rotateMenu->AppendRadioItem(wRot0, _T("0"));
|
||||||
|
rotateMenu->AppendRadioItem(wRot90, _T("90"));
|
||||||
|
rotateMenu->AppendRadioItem(wRot180, _T("180"));
|
||||||
|
rotateMenu->AppendRadioItem(wRot270, _T("270"));
|
||||||
|
}
|
||||||
|
viewMenu->AppendSubMenu(rotateMenu, _T("Rotate"));
|
||||||
viewMenu->AppendSeparator();
|
viewMenu->AppendSeparator();
|
||||||
viewMenu->Append(wFrameCounter, _T("&Display Frame Counter"));
|
viewMenu->Append(wFrameCounter, _T("&Display Frame Counter"));
|
||||||
viewMenu->Append(wFPS, _T("&Display FPS"));
|
viewMenu->Append(wFPS, _T("&Display FPS"));
|
||||||
|
@ -613,6 +698,7 @@ DesmumeFrame::DesmumeFrame(const wxString& title)
|
||||||
|
|
||||||
// CreateStatusBar(2);
|
// CreateStatusBar(2);
|
||||||
// SetStatusText("Welcome to Desmume!");
|
// SetStatusText("Welcome to Desmume!");
|
||||||
|
SetClientSize(256,384);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
Loading…
Reference in New Issue