Update to v075r02 release.

byuu says:

Changelog:
- added ui-libsnes directory back into source archive; make archive-all
  includes it now
- added basic HexEditor widget to phoenix/Windows
This commit is contained in:
Tim Allen 2011-02-02 21:33:35 +11:00
parent eecc085e42
commit 012cdd4b14
9 changed files with 195 additions and 20 deletions

View File

@ -65,6 +65,6 @@ clean:
-@$(call delete,*.manifest)
archive-all:
tar -cjf bsnes.tar.bz2 data gameboy libco nall obj out phoenix ruby snes ui ui-gameboy Makefile cc.bat clean.bat sync.sh
tar -cjf bsnes.tar.bz2 data gameboy libco nall obj out phoenix ruby snes ui ui-gameboy ui-libsnes Makefile cc.bat clean.bat sync.sh
help:;

View File

@ -2,19 +2,16 @@
#define NALL_PUBLIC_CAST_HPP
//this is a proof-of-concept-*only* C++ access-privilege elevation exploit.
//it allows full access to both protected and private member variables, objects and functions
//from the global scope, regardless of inheritance and/or friendship privileges.
//the code itself is 100% legal C++, per C++98 section 14.7.2 paragraph 8:
//"Access checking rules do not apply to names in explicit instantiations."
//C++0x variadic templates are used simply to allow public_cast name to be used
//on second derived class name for simplification, however the basic idea also
//works on C++98.
//this code is 100% legal C++, per C++98 section 14.7.2 paragraph 8:
//"access checking rules do not apply to names in explicit instantiations."
//usage example:
//struct N { typedef void (Class::*)(); };
//template class public_cast<N, &Class::Function>;
//(class.*public_cast<N>::value)();
//template class public_cast<N, &Class::Reference>;
//(class.*public_cast<N>::value);
//Class::Reference may be public, protected or private
//Class::Reference may be a function, object or variable
namespace nall {
template<typename T, typename T::type... P> struct public_cast;
@ -26,13 +23,10 @@ namespace nall {
template<typename T> typename T::type public_cast<T>::value;
template<typename T, typename T::type P> struct public_cast<T, P> : public_cast<T> {
struct ref_t {
ref_t() { public_cast<T>::value = P; }
};
static ref_t ref;
static typename T::type value;
};
template<typename T, typename T::type P> typename public_cast<T, P>::ref_t public_cast<T, P>::ref;
template<typename T, typename T::type P> typename T::type public_cast<T, P>::value = public_cast<T>::value = P;
}
#endif

View File

@ -116,7 +116,7 @@ HexEditor::HexEditor() {
//internal
bool HexEditor::keyPress(unsigned scancode) {
if(!onRead && !onWrite) return false;
if(!onRead || !onWrite) return false;
unsigned position = cursorPosition();
unsigned lineWidth = 10 + (hexEditor->columns * 3) + 1 + (hexEditor->columns) + 1;

View File

@ -30,6 +30,10 @@ void EditBox::setText(const string &text) {
object->locked = false;
}
void EditBox::setCursorPosition(unsigned position) {
Edit_SetSel(widget->window, position, position);
}
void EditBox::setEditable(bool editable) {
SendMessage(widget->window, EM_SETREADONLY, editable == false, (LPARAM)0);
}

View File

@ -0,0 +1,149 @@
static LRESULT CALLBACK HexEditor_WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
HexEditor &self = *(HexEditor*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
switch(msg) {
case WM_CHAR: {
if(self.keyPress(wparam)) return 0;
}
}
return self.hexEditor->windowProc(hwnd, msg, wparam, lparam);
}
void HexEditor::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height) {
widget->window = CreateWindowEx(
WS_EX_CLIENTEDGE,
L"EDIT", L"",
WS_CHILD | WS_TABSTOP | WS_VISIBLE | ES_READONLY | ES_MULTILINE | ES_WANTRETURN,
x, y, width, height,
parent.widget->window, (HMENU)object->id, GetModuleHandle(0), 0
);
SetWindowLongPtr(widget->window, GWLP_USERDATA, (LONG_PTR)this);
SendMessage(widget->window, WM_SETFONT, (WPARAM)(parent.window->defaultFont ? parent.window->defaultFont : OS::os->monospaceFont), 0);
hexEditor->windowProc = (LRESULT CALLBACK (*)(HWND, UINT, LPARAM, WPARAM))GetWindowLongPtr(widget->window, GWLP_WNDPROC);
SetWindowLongPtr(widget->window, GWLP_WNDPROC, (LONG_PTR)HexEditor_WindowProc);
}
void HexEditor::setSize(unsigned size) {
hexEditor->size = size;
update();
}
void HexEditor::setOffset(unsigned offset) {
hexEditor->offset = offset;
update();
}
void HexEditor::setColumns(unsigned columns) {
hexEditor->columns = columns;
update();
}
void HexEditor::setRows(unsigned rows) {
hexEditor->rows = rows;
update();
}
void HexEditor::update() {
if(!onRead) {
SetWindowText(widget->window, L"");
return;
}
//modifying text resets cursor position to zero, save position so we can restore it later
unsigned cursorPosition = Edit_GetSel(widget->window);
string output;
unsigned offset = hexEditor->offset;
for(unsigned row = 0; row < hexEditor->rows; row++) {
output.append(hex<8>(offset));
output.append(" ");
string hexdata;
string ansidata = " ";
for(unsigned column = 0; column < hexEditor->columns; column++) {
if(offset < hexEditor->size) {
uint8_t data = onRead(offset++);
hexdata.append(hex<2>(data));
hexdata.append(" ");
char buffer[2] = { data >= 0x20 && data <= 0x7e ? (char)data : '.', 0 };
ansidata.append(buffer);
} else {
hexdata.append(" ");
ansidata.append(" ");
}
}
output.append(hexdata);
output.append(ansidata);
if(offset >= hexEditor->size) break;
if(row != hexEditor->rows - 1) output.append("\r\n");
}
SetWindowText(widget->window, utf16_t(output));
Edit_SetSel(widget->window, LOWORD(cursorPosition), HIWORD(cursorPosition));
}
bool HexEditor::keyPress(unsigned scancode) {
if(!onRead || !onWrite) return false;
unsigned position = LOWORD(Edit_GetSel(widget->window));
unsigned lineWidth = 10 + (hexEditor->columns * 3) + 1 + (hexEditor->columns) + 2;
unsigned cursorY = position / lineWidth;
unsigned cursorX = position % lineWidth;
//convert scancode to hex nibble
if(scancode >= '0' && scancode <= '9') scancode = scancode - '0';
else if(scancode >= 'A' && scancode <= 'F') scancode = scancode - 'A' + 10;
else if(scancode >= 'a' && scancode <= 'f') scancode = scancode - 'a' + 10;
else return false;
if(cursorX >= 10) {
//not on an offset
cursorX -= 10;
if((cursorX % 3) != 2) {
//not on a space
bool cursorNibble = (cursorX % 3) == 1; //0 = high, 1 = low
cursorX /= 3;
if(cursorX < hexEditor->columns) {
//not in ANSI region
unsigned offset = hexEditor->offset + (cursorY * hexEditor->columns + cursorX);
if(offset >= hexEditor->size) return false; //do not edit past end of file
uint8_t data = onRead(offset);
//write modified value
if(cursorNibble == 1) {
data = (data & 0xf0) | (scancode << 0);
} else {
data = (data & 0x0f) | (scancode << 4);
}
onWrite(offset, data);
//auto-advance cursor to next nibble/byte
position++;
if(cursorNibble && cursorX != hexEditor->columns - 1) position++;
Edit_SetSel(widget->window, position, position);
//refresh output to reflect modified data
update();
}
}
}
return true;
}
HexEditor::HexEditor() {
hexEditor = new HexEditor::Data;
hexEditor->windowProc = 0;
hexEditor->size = 0;
hexEditor->offset = 0;
hexEditor->columns = 16;
hexEditor->rows = 16;
}
HexEditor::~HexEditor() {
delete[] hexEditor;
}

View File

@ -53,6 +53,14 @@ struct EditBox::Data {
unsigned height;
};
struct HexEditor::Data {
LRESULT CALLBACK (*windowProc)(HWND, UINT, LPARAM, WPARAM);
unsigned size;
unsigned offset;
unsigned columns;
unsigned rows;
};
struct HorizontalSlider::Data {
unsigned position;
};

View File

@ -1,4 +1,5 @@
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <io.h>
#include <direct.h>
@ -19,6 +20,7 @@ namespace phoenix {
#include "checkbox.cpp"
#include "combobox.cpp"
#include "editbox.cpp"
#include "hexeditor.cpp"
#include "horizontalslider.cpp"
#include "label.cpp"
#include "listbox.cpp"
@ -45,7 +47,7 @@ void OS::initialize() {
os = new OS::Data;
os->proportionalFont = Font_createFont("Tahoma", 8, false, false);
os->monospaceFont = Font_createFont("Courier New", 8, false, false);
os->monospaceFont = Font_createFont("Lucida Console", 8, false, false);
WNDCLASS wc;
wc.cbClsExtra = 0;

View File

@ -163,6 +163,7 @@ struct EditBox : Widget {
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
nall::string getText();
void setText(const nall::string &text);
void setCursorPosition(unsigned position);
void setEditable(bool editable = true);
void setWordWrap(bool wordWrap = true);
EditBox();
@ -171,6 +172,23 @@ struct EditBox : Widget {
Data *editBox;
};
struct HexEditor : Widget {
nall::function<uint8_t (unsigned)> onRead;
nall::function<void (unsigned, uint8_t)> onWrite;
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height);
void setSize(unsigned size);
void setOffset(unsigned offset);
void setColumns(unsigned columns);
void setRows(unsigned rows);
void update();
HexEditor();
~HexEditor();
//private:
struct Data;
Data *hexEditor;
bool keyPress(unsigned scancode);
};
struct HorizontalSlider : Widget {
nall::function<void ()> onChange;
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, unsigned length);

View File

@ -1,7 +1,7 @@
namespace SNES {
namespace Info {
static const char Name[] = "bsnes";
static const char Version[] = "075.01";
static const char Version[] = "075.02";
static const unsigned SerializerVersion = 18;
}
}