Toggle menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Code/RPGMaker: Difference between revisions

From ZeroWiki
imported>ppparkje
No edit summary
(Repair batch-0001 pages from live compare)
 
(8 intermediate revisions by one other user not shown)
Line 18: Line 18:
 
 
  // making background plane
  // making background plane
  float[] coordinates = { // position of vertices
  float[] coordinates = { // position of vertices
  0.0f, 0.0f, 0.0f,
  0.0f, 0.0f, 0.0f,
  m_width, 0.0f, 0.0f,
  m_width, 0.0f, 0.0f,
Line 25: Line 25:
  };
  };
   
   
  float[] uvs = { // how uv mapped?
  float[] uvs = { // how uv mapped?
  0.0f, 0.0f,  
  0.0f, 0.0f,  
  1.0f, 0.0f,  
  1.0f, 0.0f,  
Line 32: Line 32:
  };
  };
 
 
  int[] indices = { // index of each coordinate
  int[] indices = { // index of each coordinate
  0, 2, 1,
  0, 2, 1,
  1, 2, 3
  1, 2, 3
Line 92: Line 92:
  float z = -10f;
  float z = -10f;
 
 
  float[] coords = {
  float[] coords = {
  x1, y1, z, // up left
  x1, y1, z, // up left
  x1, y2, z, // bottom left
  x1, y2, z, // bottom left
Line 99: Line 99:
  };
  };
 
 
  float[] uvs = {
  float[] uvs = {
  0f, 0f,
  0f, 0f,
  0f, 1f,
  0f, 1f,
Line 106: Line 106:
  };
  };
 
 
  int[] indices = {
  int[] indices = {
  0, 1, 2,
  0, 1, 2,
  2, 1, 3
  2, 1, 3
Line 145: Line 145:
  normal.scale(width/2.0f);
  normal.scale(width/2.0f);
 
 
  float[] coords = {
  float[] coords = {
  (vStart.x + normal.x), (vStart.y + normal.y), z,
  (vStart.x + normal.x), (vStart.y + normal.y), z,
  (vStart.x - normal.x), (vStart.y - normal.y), z,
  (vStart.x - normal.x), (vStart.y - normal.y), z,
Line 152: Line 152:
  };
  };
 
 
  float[] uvs = {
  float[] uvs = {
  0f, 0f,
  0f, 0f,
  0f, 1f,
  0f, 1f,
Line 159: Line 159:
  };
  };
 
 
  int[] indices = {
  int[] indices = {
  0, 2, 1,
  0, 2, 1,
  1, 2, 3
  1, 2, 3
Line 188: Line 188:
  }
  }


= Actors.rvdata Parser =
= Table 클래스의 구현 =


public class RMFileParser {
class IDFinder {
static final int TYPE_SIG = 0;
static final int TYPE_INT = 1;
static final int TYPE_BOOL = 2;
static final int TYPE_STR = 3;
static final int TYPE_TABLE = 4;
static final int TYPE_PARAM = 5;
public IDFinder(String name, int type) {
this.name = name;
this.type = type;
}
boolean addChar(byte c){
if(index >= name.length())
return false;
if(name.charAt(index) == c) {
index++;
if(index == name.length())
return true;
}
else {
index = 0;
}
return false;
}
public String name = "";
public int type;
private int index = 0;
}
private IDFinder[] finder = {
new IDFinder("@id", IDFinder.TYPE_INT),
new IDFinder("@name", IDFinder.TYPE_STR),
new IDFinder("Table", IDFinder.TYPE_TABLE),
new IDFinder("@class_id", IDFinder.TYPE_INT),
new IDFinder("@weapon_id", IDFinder.TYPE_INT),
new IDFinder("@armor1_id", IDFinder.TYPE_INT),
new IDFinder("@armor2_id", IDFinder.TYPE_INT),
new IDFinder("@armor3_id", IDFinder.TYPE_INT),
new IDFinder("@armor4_id", IDFinder.TYPE_INT),
new IDFinder("@exp_basis", IDFinder.TYPE_INT),
new IDFinder("@face_name", IDFinder.TYPE_STR),
new IDFinder("@parameters", IDFinder.TYPE_PARAM),
new IDFinder("@face_index", IDFinder.TYPE_INT),
new IDFinder("@super_guard", IDFinder.TYPE_BOOL),
new IDFinder("@auto_battle", IDFinder.TYPE_BOOL),
new IDFinder("@pharmacology", IDFinder.TYPE_BOOL),
new IDFinder("@initial_level", IDFinder.TYPE_INT),
new IDFinder("@exp_inflation", IDFinder.TYPE_INT),
new IDFinder("@fix_equipment", IDFinder.TYPE_BOOL),
new IDFinder("@character_name", IDFinder.TYPE_STR),
new IDFinder("@critical_bonus", IDFinder.TYPE_BOOL),
new IDFinder("@character_index", IDFinder.TYPE_INT),
new IDFinder("@two_swords_style", IDFinder.TYPE_BOOL),
new IDFinder("RPG::Actor", IDFinder.TYPE_SIG)
};
   
   
# Table class
public static void main(String[] args)
# a 3-dimensional array2 stores 2Byte integer
{
# Uses hash table internally.
//test
class Table
new RMFileParser();
  def initialize(xsize=1, ysize=1, zsize=1)
}
    resize(xsize, ysize, zsize)
  end
public RMFileParser()
 
{
  def resize xsize, ysize, zsize
try {
    @array = Hash.new
FileInputStream fis = new FileInputStream(new File("testdata/Project1-/Data/Actors.rvdata"));
    @xsize = xsize
newParse(fis);
    @ysize = ysize
fis.close();
    @zsize = zsize
} catch (FileNotFoundException e) {
  end
// TODO Auto-generated catch block
 
e.printStackTrace();
  def self.resize xsize, ysize, zsize
} catch (IOException e) {
    #puts "resize to (#{xsize}, #{ysize}, #{zsize})"
// TODO Auto-generated catch block
    @array = Hash.new
e.printStackTrace();
    @xsize = xsize
}
    @ysize = ysize
}
    @zsize = zsize
  end
public void newParse(InputStream is) throws IOException
{
  def [] *args
is.skip(3);
    x=0
int data = 0;
    y=0
List<IDFinder> argList = new ArrayList<IDFinder>();
    z=0
boolean bFound = false;
    if args.length > 0
boolean firstChar = true;
      x = args[0]
while((data = is.read()) != -1) {
    end
if(bFound && data == 0x3a)
    if args.length > 1
bFound = false;
      y = args[1]
else if(bFound && data == 0x3b) {
    end
firstChar = false;
    if args.length > 2
bFound = false;
      z = args[2]
continue;
    end 
}
    return @array[[x, y, z]]
  end
for(int i=0; firstChar && i<finder.length && !bFound; i++) {
 
if(finder[i].addChar((byte)data)) {
  def []= *args
Util.LOGD("found: " + finder[i].name);
    value = args[args.size-1]
bFound = true;
    args.delete_at(args.size-1)
argList.add(finder[i]);
   
String result = null;
    x=0
switch(finder[i].type) {
    y=0
    z=0
case IDFinder.TYPE_BOOL:
    if args.length > 0
result = String.valueOf(is.read() == 'T');
      x = args[0]
break;
    end
    if args.length > 1
case IDFinder.TYPE_INT:
      y = args[1]
is.skip(1);
    end
int v = is.read();
    if args.length > 2
result = String.valueOf(v == 0 ? 0 : v-5);
      z = args[2]
break;
    end
case IDFinder.TYPE_PARAM:
    @array[[x, y, z]] = value
result = String.valueOf((char)is.read());
  end
break;
 
  def self._load args
case IDFinder.TYPE_SIG:
    #puts "load table"
result = finder[i].name;
    header = args.unpack("l5")
break;
    table = args.unpack("@20s*")
    #puts header.inspect
case IDFinder.TYPE_STR:
    #puts table.inspect
is.skip(2);
   
byte[] arr = new byte[100];
    obj = Table.new(header[1], header[2], header[3])
for(int j=0;; j++) {
   
byte b = (byte)is.read();
    i=-1
if(b == 0x3a) {
    for z in 0 ... obj.zsize
result = new String(arr, 0, j);
      for y in 0 ... obj.ysize
bFound = false;
        for x in 0 ... obj.xsize
break;
          obj[x, y, z] = table[i = i+1]
}
          #puts "array put #{table[i]}"
else {
        end
arr[j] = b;
      end
}
    end
   
}
    return obj
break;
  end
case IDFinder.TYPE_TABLE:
  attr_accessor :xsize
result = "Table start: ";
  attr_accessor :ysize
read_table(is);
  attr_accessor :zsize
break;
end
}
 
= Color 클래스의 구현 =
Util.LOGD(result);
  알만툴에서 사용하는 Color 클래스이다.
break;
}
}
if(!firstChar && !bFound) {
int index = get_int(data);
Util.LOGD("found: " + argList.get(index).name);
bFound = true;
if(argList.get(index).name.equals("Table")) {
Util.LOGD("table found");
read_table(is);
}
}
}
Util.LOGD("" + argList.size());
}
private int get_int(int data)
{
return data <= 0 ? 0 : data - 5;
}
private void read_table(InputStream is)
{
try {
is.skip(0x17);
for(int i=0; i<100; i++) {
System.out.print("level " + i + ": ");
for(int j=0; j<6; j++) {
int v = readShort(is);
System.out.print(v + " ");
}
System.out.println();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private int readShort(InputStream is) throws IOException
{
return is.read() + (is.read() << 8);
}
  }


= Actors.rvdata Parser: advanced(위 parser 코드와 이어짐) =
내부적으로 자바의 java.awt.Color 클래스를 가지고 있으며 이를 이용하여 모든 값을 주고받는다.


루비의 Color와 자바의 Color이 이름이 같기 때문에 자바의 Color을 임시 모듈에 담아 모호성을 해결하였다.
require 'java'
   
   
# use temporary namespace(module) to solve ambiguous class name
public void parse2(InputStream is) throws IOException
  module AA
{
  import 'java.awt.Color'
is.skip(3);
  end
int numChar = is.read()-6;
Util.LOGD("캐릭터 수: " + numChar);
int data;
byte[] buf;
while((data = is.read()) != -1) {
// RPG::Actor(시그니쳐) 찾은 경우
if(finder_actor[0].addChar((byte) data)) {
// 입력받을 클래스 변수 수
int numArgs = get_int(is.read());
// 변수 순서가 저장될 행렬
String result = null;
List<String> argList = new ArrayList<String>();
// 첫번째 캐릭터
for(int i=0; i<numArgs; i++) {
for(;is.read() != 0x3a;); // 다음 구분자까지 읽는다
// 이름 길이
int elementNameLen = get_int(is.read());
buf = new byte[elementNameLen];
// 변수 이름 입력
is.read(buf);
result = new String(buf);
// 변수에 들일 값 읽기
String value = getValue(is);
Util.LOGD("발견!" + result + " value: " + value);
argList.add(result);
   
// 테이블은 있으면 개수에 포함하지 않는다
if(value.equals("u"))
i--;
}
// 그 이후 캐릭터들
for(int i=0; i<numChar-1; i++) {
Util.LOGD((i+2) + "번째 캐릭터 시작");
for(;is.read() != 0x3b;); // 시작 시그니쳐 건너뜀
for(int j=0; j<numArgs; j++) {
for(;is.read() != 0x3b;); // 다음 구분자까지
// 변수 순서
int index = get_int(is.read());
String value = getValue(is);
// 변수값 읽기
Util.LOGD("발견!" + argList.get(index-1) + " value: " + value);
   
// 테이블은 있으면 개수에 포함하지 않는다
if(value.equals("u"))
j--;
}
}
}
}
}
   
   
class Color
 
  attr_reader :object
 
  def initialize red, green, blue, alpha=255
    @object = AA::Color.new(red, green, blue, alpha)
  end
 
  def set red, green, blue, alpha=255
    @object = AA::Color.new(red, green, blue, alpha)
  end
   
   
  def red
    return @object.getRed
private String getValue(InputStream is) throws IOException
  end
{
  def green
byte type = (byte) is.read();
    return @object.getGreen
String result = null;
  end
switch(type) {
  def blue
case 0x02: // table
    return @object.getBlue
result = "table start";
  end
read_table(is);
  def alpha
break;
    return @object.getAlpha
case '"': //str
  end
int len = get_int(is.read());
 
if(len < 0)
  def self._load args
len = readShort(is);
    # convert to floting point value
byte[] str = new byte[len];
    value = args.unpack("d4")
is.read(str);
    return  Color.new(value[0].to_i, value[1].to_i, value[2].to_i, value[3].to_i)
result = new String(str);
  end
break;
 
case 'i': // int
  def to_i
int value = get_int(is.read());
    return (red | (green << 8) | (blue << 16) | (alpha << 24))
result = String.valueOf(value);
  end
break;
 
case 'T':
  def red= r
case 'F':
    r = adjust_value(r, 0, 255)
result = String.valueOf(type == 'T');
    set(r, green, blue, alpha)
break;
  end
case 'u':
 
result = "u";
  def green= g
}
    g = adjust_value(g, 0, 255)
    set(red, g, blue, alpha)
return result;
  end
}
 
 
  def blue= b
    b = adjust_value(b, 0, 255)
    set(red, green, b, alpha)
  end
 
  def alpha= a
    a = adjust_value(a, 0, 255)
    set(red, green, blue, a)
  end
end

Latest revision as of 23:56, 26 March 2026

Orthogonal projection coordinate system 만들기

	public void onSurfaceChanged(GL10 gl, int width, int height) {
		
		this.m_width = width;
		this.m_height = height;
		
		if(buffer == null) {
			
			Util.LOGD("make framebuffer");
			world = new World();
			m_cam = world.getCamera();
			
			// light mass
			world.setAmbientLight(0xff, 0xff, 0xff);
			
			// making background plane
			float[] coordinates = { // position of vertices
				0.0f, 0.0f, 0.0f,
				m_width, 0.0f, 0.0f,
				0.0f, m_height, 0.0f,
				m_width, m_height, 0.0f
			};

			float[] uvs = { // how uv mapped?
				0.0f, 0.0f, 
				1.0f, 0.0f, 
				0.0f, 1.0f, 
				1.0f, 1.0f
			};
			
			int[] indices = { // index of each coordinate
				0, 2, 1,
				1, 2, 3
			};

			// make plane
			Object3D plane = new Object3D(coordinates, uvs, indices, RMObject2D.getTextureIDByColor(Color.white));
			plane.build();
			Util.LOGD("center: " + plane.getTransformedCenter());
			world.addObject(plane);
			
			// FOV settings
			m_cam.setFOVLimits(0.1f, 2.0f);
			m_cam.setFOV(0.1f);
			
			// set up camera
			// z = (width/2) / tan(fov/2)
			m_cam.setPosition(m_width/2, m_height/2, (float) -(m_width/2/Math.tan(m_cam.getFOV()/2.0f)));
			m_cam.lookAt(plane.getTransformedCenter());
			fixCubePosition();
			
			// configuration to view far object
			Config.farPlane = Math.abs(m_cam.getPosition().z) + 1000f;
		}
		
		// make framebuffer
		if(buffer != null)
			buffer.dispose();
		buffer = new FrameBuffer(m_width, m_height, FrameBuffer.SAMPLINGMODE_NORMAL);
	}


FillBox class

package cau.rpg.maker.object;

import java.awt.Color;

import javax.vecmath.Vector2f;

import com.threed.jpct.Object3D;

public class RMFillBox extends RMObject2D {

	public RMFillBox(float x1, float y1, float x2, float y2, Color color)
	{
		init(x1, y1, x2, y2, color);
	}
	
	public RMFillBox(Vector2f vStart, Vector2f vEnd, Color color)
	{
		init(vStart.x, vStart.y, vEnd.x, vEnd.y, color);
	}
	
	private void init(float x1, float y1, float x2, float y2, Color color)
	{
		if(x1 >= x2 || y1 >= y2)
			return;
		
		float z = -10f;
		
		float[] coords = {
			x1, y1, z,		// up left
			x1, y2, z,		// bottom left
			x2, y1, z,		// up right
			x2, y2, z		// bottom right corner
		};
		
		float[] uvs = {
			0f, 0f,
			0f, 1f,
			1f, 0f,
			1f, 1f
		};
		
		int[] indices = {
			0, 1, 2,
			2, 1, 3
		};
		
		m_polygon = new Object3D(coords, uvs, indices, getTextureIDByColor(color));
	}
}

2D line class

package cau.rpg.maker.object;

import java.awt.Color;

import javax.vecmath.Vector2f;
import javax.vecmath.Vector3f;

import com.threed.jpct.Object3D;

public class RMLine extends RMObject2D {
	
	private static final Vector3f vectorZ = new Vector3f(0, 0, -1);
	
	public RMLine(Vector2f vStart, Vector2f vEnd, float width, Color color)
	{
		float z = -10f;
		Vector3f v3Start = new Vector3f(vStart.x, vStart.y, z);
		Vector3f v3End = new Vector3f(vEnd.x, vEnd.y, z);
		
		// line vector
		Vector3f lineVector = new Vector3f();
		lineVector.sub(v3End, v3Start);
		
		// calc normal vector of line
		Vector3f normal = new Vector3f();
		normal.cross(lineVector, vectorZ);
		normal.normalize();
		normal.scale(width/2.0f);
		
		float[] coords = {
			(vStart.x + normal.x), (vStart.y + normal.y), z,
			(vStart.x - normal.x), (vStart.y - normal.y), z,
			(vEnd.x + normal.x), (vEnd.y + normal.y), z,
			(vEnd.x - normal.x), (vEnd.y - normal.y), z
		};
		
		float[] uvs = {
			0f, 0f,
			0f, 1f,
			1f, 0f,
			1f, 1f
		};
		
		int[] indices = {
			0, 2, 1,
			1, 2, 3
		};
		
		m_polygon = new Object3D(coords, uvs, indices, getTextureIDByColor(color));
	}

}

Interpolation

	public void setDepth(float depth)
	{
		float delta = depth - this.depth;
		
		// move object
		SimpleVector curPosition = m_polygon.getTransformedCenter();
		SimpleVector toCam = MainRenderer.getCamera().getPosition().calcSub(curPosition);
		float a = MainRenderer.getCamera().getPosition().z - this.depth;
		toCam.scalarMul(delta/a);
		m_polygon.translate(toCam);
		Util.LOGD("translate to " + toCam);
		
		// scale
		m_polygon.scale((a-delta)/a);
		
		this.depth = depth;
	}

Table 클래스의 구현

# Table class
# a 3-dimensional array2 stores 2Byte integer
# Uses hash table internally.
class Table
  def initialize(xsize=1, ysize=1, zsize=1)
    resize(xsize, ysize, zsize)
  end
  
  def resize xsize, ysize, zsize
    @array = Hash.new
    @xsize = xsize
    @ysize = ysize
    @zsize = zsize
  end
  
  def self.resize xsize, ysize, zsize
    #puts "resize to (#{xsize}, #{ysize}, #{zsize})"
    @array = Hash.new
    @xsize = xsize
    @ysize = ysize
    @zsize = zsize
  end

  def [] *args
    x=0
    y=0
    z=0
    if args.length > 0
      x = args[0]
    end
    if args.length > 1
      y = args[1]
    end
    if args.length > 2
      z = args[2]
    end  
    return @array[[x, y, z]]
  end
  
  def []= *args
    value = args[args.size-1]
    args.delete_at(args.size-1)
    
    x=0
    y=0
    z=0
    if args.length > 0
      x = args[0]
    end
    if args.length > 1
      y = args[1]
    end
    if args.length > 2
      z = args[2]
    end

    @array[[x, y, z]] = value
  end
  
  def self._load args
    #puts "load table"
    header = args.unpack("l5")
    table = args.unpack("@20s*")
    #puts header.inspect
    #puts table.inspect
    
    obj = Table.new(header[1], header[2], header[3])
    
    i=-1
    for z in 0 ... obj.zsize
      for y in 0 ... obj.ysize
        for x in 0 ... obj.xsize
          obj[x, y, z] = table[i = i+1]
          #puts "array put #{table[i]}"
        end
      end
    end
    
    return obj
  end

  attr_accessor :xsize
  attr_accessor :ysize
  attr_accessor :zsize
end

Color 클래스의 구현

알만툴에서 사용하는 Color 클래스이다.
내부적으로 자바의 java.awt.Color 클래스를 가지고 있으며 이를 이용하여 모든 값을 주고받는다.
루비의 Color와 자바의 Color이 이름이 같기 때문에 자바의 Color을 임시 모듈에 담아 모호성을 해결하였다.
require 'java'

# use temporary namespace(module) to solve ambiguous class name
module AA
  import 'java.awt.Color'
end

class Color
  
  attr_reader :object
  
  def initialize red, green, blue, alpha=255
    @object = AA::Color.new(red, green, blue, alpha)
  end
  
  def set red, green, blue, alpha=255
    @object = AA::Color.new(red, green, blue, alpha)
  end

  def red
    return @object.getRed
  end
  def green
    return @object.getGreen
  end
  def blue
    return @object.getBlue
  end
  def alpha
    return @object.getAlpha
  end
  
  def self._load args
    # convert to floting point value
    value = args.unpack("d4")
    return  Color.new(value[0].to_i, value[1].to_i, value[2].to_i, value[3].to_i)
  end
  
  def to_i
    return (red | (green << 8) | (blue << 16) | (alpha << 24))
  end
  
  def red= r
    r = adjust_value(r, 0, 255)
    set(r, green, blue, alpha)
  end
  
  def green= g
    g = adjust_value(g, 0, 255)
    set(red, g, blue, alpha)
  end
  
  def blue= b
    b = adjust_value(b, 0, 255)
    set(red, green, b, alpha)
  end
  
  def alpha= a
    a = adjust_value(a, 0, 255)
    set(red, green, blue, a)
  end
end