gabehabe Cool blog, bro.

28Sep/090

My First Android App: Brainfuck

My first app!

** EDIT: Just realised input doesn’t work: It brings up the input dialog, but I forgot to save it anywhere! Guess I was a little too excited to get publishing ;). I’ll try to find time to fix it tomorrow! Apologies! **

Download:
Download on android!

Okay, so it’s not gonna get a very good rating… it’s not very attractive, and I really don’t think many people are going to understand Brainfuck.

That said, it was a fun little app to write… and I must admit, I really didn’t give the android SDK a fair chance. (Mind, it’s changed a hell of a lot since I first tried it back when android was first released to the general public!)

Code for the app, broken into two parts: (the activity and the layout)

First off, the main code for the Java activity:

package gabehabe.brainfuck;
 
import android.app.TabActivity;
import android.os.Bundle;
import android.widget.TabHost;
import android.widget.EditText;
import android.widget.TextView;
import android.text.InputFilter;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.widget.TabHost.OnTabChangeListener;
 
public class Brainfuck extends TabActivity implements OnTabChangeListener {
	String input;
	TabHost tabs;
 
	@Override
	public void onCreate(Bundle savedInstanceState) {
	    super.onCreate(savedInstanceState);
	    setContentView(R.layout.main);
 
	    this.tabs = getTabHost();
 
	    tabs.addTab(tabs.newTabSpec("tab_code").setIndicator("Code").setContent(R.id.code));
	    tabs.addTab(tabs.newTabSpec("tab_run").setIndicator("Run").setContent(R.id.interpreted));
	    tabs.addTab(tabs.newTabSpec("tab_help").setIndicator("Help").setContent(R.id.help));
	    tabs.setOnTabChangedListener(this);
 
 
	    tabs.setCurrentTab(0);
	}
 
	@Override
	public void onTabChanged(String label) {
		if(label == "tab_run") {
			final Brainfuck bf = this;
			final TextView interpreted = (TextView)this.findViewById(R.id.interpreted);
			interpreted.setText("");
			final EditText edt = (EditText)this.findViewById(R.id.code);
			String t = edt.getText().toString();
			int bytes_pos = 0;
			int loop_pos = -1;
			char [] bytes = new char[300];
			// initialise and make sure everything's 0
			for(int i = 0; i < 300; i++) {
				bytes[i] = 0;
			}
			for(int i = 0; i < t.length(); i++) {
				switch(t.charAt(i)) {
					case '+':
						++bytes[bytes_pos];
						break;
					case '-':
						--bytes[bytes_pos];
						break;
					case '>':
						++bytes_pos;
						break;
					case '< ':
						--bytes_pos;
						break;
					case '.':
						StringBuffer b = new StringBuffer();
						b.append(interpreted.getText()).append(bytes[bytes_pos]);
						interpreted.setText(b.toString());
						break;
					case ',':
					    AlertDialog.Builder alert = new AlertDialog.Builder(this);
 
					    alert.setTitle("Enter Character");
					    alert.setMessage("Program is requesting input!");
 
					    // Set an EditText view to get user input 
					    final EditText input = new EditText(this);
					    InputFilter[] FilterArray = new InputFilter[1];
					    FilterArray[0] = new InputFilter.LengthFilter(1);
					    input.setFilters(FilterArray);
 
					    alert.setView(input);
 
					    alert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
					    public void onClick(DialogInterface dialog, int whichButton) {
					    	bf.input = input.getText().toString();
					      }
					    });
 
					    alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
					      public void onClick(DialogInterface dialog, int whichButton) {
					    	 bf.input = "";
					      }
					    });
					    alert.show();
					    break;
					case '[':
						loop_pos = i;
						break;
					case ']':
						if (loop_pos != -1) {
							if(bytes[bytes_pos] == 255) { // stupid java... ¬_¬
								bytes[bytes_pos] = 0;
							}
							if (bytes[bytes_pos] != 0) {
								i = loop_pos;
							} else {
								loop_pos = -1;
							}
						}
						break;
				}
			}
		}
	}
}

And now the code for the actual layout (XML format)

< ?xml version="1.0" encoding="utf-8"?>
<tabhost xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <linearlayout android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <tabwidget android:id="@android:id/tabs"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
        <framelayout android:id="@android:id/tabcontent"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent">
 
            /* tab 1 -- code entry */
            <edittext android:id="@+id/code" 
              android:layout_width="fill_parent" 
              android:layout_height="fill_parent" 
              android:background="@android:drawable/editbox_background"
            />
 
            /* tab 2 -- run */
            <scrollview xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent">
              <textview android:id="@+id/interpreted"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent" 
              />
            </scrollview>
            /* tab 3 -- help */
            <scrollview xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent">
              <textview android:id="@+id/help"
      	          android:layout_width="fill_parent"
             	  android:layout_height="fill_parent" 
                  android:text="@string/help"
              />
            </scrollview>
    	</framelayout>
    </linearlayout>
</tabhost>

I'll no doubt be adding stuff, a menu for snippets, perhaps saving files and stuff... all good fun. Watch this space! :)

31Aug/092

A Fresh Start

So here we are again. :\

Those of you who know me should know by now that I’ve had a whole bunch of blogs in the past, very few of which lasted very long. But this one’s gonna be different! I’ve finally decided to put gabehabe.com to use, and write a blog, mainly driven around programming, but it’ll probably contain a whole bunch of rants, too. Like how Apple suck.

I’m actually gonna get to work on my first proper entry for this already, about cracking WEP. Yeah, nice start to a blog, right?

By the way, WordPress is simple but fucking confusing as hell at the same time.

Filed under: General 2 Comments