EXPORT void CALL DebugMemWrite64(unsigned int address, unsigned long long value) { #ifdef DBG if ((address & 3) == 0) write_memory_64(address, value); else write_memory_64_unaligned(address, value); #else DebugMessage(M64MSG_ERROR, "Bug: DebugMemWrite64() called, but Debugger not supported in Core library"); #endif }
//Cell edit handler. //Todo: why is this getting called on double-click when the text box hasn't //popped up yet? static void on_cell_edit(GtkCellRendererText *renderer, gchar *path, gchar *new_text, gpointer user_data) { int i, j; GtkTreeIter iter; GValue newval, val_addr, val_type, val_offset; uint32 addr, type, value, offset; uint64 value64; float valuef; double valued; char formatted[18]; //for reading hex64 values gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(store), &iter, path); memset(&newval, 0, sizeof(newval)); memset(&val_addr, 0, sizeof(val_addr)); memset(&val_type, 0, sizeof(val_type)); memset(&val_offset, 0, sizeof(val_offset)); switch((long)user_data) //column number { case Col_Name: g_value_init(&newval, G_TYPE_STRING); g_value_set_string(&newval, new_text); break; case Col_Value: //Get address gtk_tree_model_get_value(GTK_TREE_MODEL(store), &iter, Col_Address, &val_addr); addr = g_value_get_int(&val_addr); //Get type gtk_tree_model_get_value(GTK_TREE_MODEL(store), &iter, Col_Type, &val_type); type = g_value_get_int(&val_type); //Get offset gtk_tree_model_get_value(GTK_TREE_MODEL(store), &iter, Col_Offset, &val_offset); offset = g_value_get_int(&val_offset); //If pointer, follow it. if(type & Type_pointer) { type &= ~Type_pointer; addr = read_memory_32(addr) + offset; } //Get new value and write. //Todo: should not write if value is invalid, or strip any non- //numeric characters from value, to avoid the annoying bug where //you make a typo and it gets set to zero. //If we just copy the current value into the variables sscanf() is //supposed to set, it won't change them when the format string is //invalid. Not sure what happens if it's too long. switch(type) { case Type_int8: sscanf(new_text, "%d", &value); write_memory_8(addr, value); break; case Type_int16: sscanf(new_text, "%d", &value); write_memory_16(addr, value); break; case Type_int32: sscanf(new_text, "%d", &value); write_memory_32(addr, value); break; case Type_int64: sscanf(new_text, "%" PRId64, &value64); write_memory_64(addr, value64); break; case Type_uint8: sscanf(new_text, "%u", &value); write_memory_8(addr, value); break; case Type_uint16: sscanf(new_text, "%u", &value); write_memory_16(addr, value); break; case Type_uint32: sscanf(new_text, "%u", &value); write_memory_32(addr, value); break; case Type_uint64: sscanf(new_text, "%" PRIu64, &value64); write_memory_64(addr, value64); break; case Type_hex8: sscanf(new_text, "%X", &value); write_memory_8(addr, value); break; case Type_hex16: sscanf(new_text, "%X", &value); write_memory_16(addr, value); break; case Type_hex32: sscanf(new_text, "%X", &value); write_memory_32(addr, value); break; case Type_hex64: //Copy new text without spaces so it can be parsed correctly. j = 0; for(i=0; new_text[i]; i++) { if(new_text[i] == ' ') continue; formatted[j] = new_text[i]; j++; } formatted[j] = '\0'; sscanf(formatted, "%" PRIX64, &value64); write_memory_64(addr, value64); break; case Type_float: //todo: the value needs to be converted to IEEE 754 somehow. sscanf(new_text, "%f", &valuef); write_memory_32(addr, (int)value); break; case Type_double: sscanf(new_text, "%lf", &valued); write_memory_64(addr, (uint64)value); break; default: printf("on_cell_edit(): unknown type %d in \"%s\", col %d\n", type, path, (int)(long)user_data); return; break; } break; case Col_Address: g_value_init(&newval, G_TYPE_INT); sscanf(new_text, "%X", &addr); g_value_set_int(&newval, addr); break; case Col_Type: //todo - this should actually be a dropdown list, not editable, //if I had any idea how to do that. if(strlen(new_text) > 2) return; //so "float" doesn't get parsed as 0xF addr = 0x7F; g_value_init(&newval, G_TYPE_INT); sscanf(new_text, "%X", &addr); if((addr & 0x7F) >= Num_Types) return; g_value_set_int(&newval, addr); break; case Col_Offset: g_value_init(&newval, G_TYPE_INT); sscanf(new_text, "%X", &addr); g_value_set_int(&newval, addr); break; } if((long)user_data != Col_Value) gtk_tree_store_set_value(store, &iter, (int)(long)user_data, &newval); }