이 블로그 검색

2022년 9월 2일 금요일

질병기록실) 코로나19 - 격리일 2022-08-24~~30.

23일 아침부터, 뭔가 목이 잠김, 오후들어서 몸살 조짐이 보임. 퇴근~~!! 집에 갔더니, 몸살이 올라옴, 9시경 집에서 코로나 테스터기를 사용함. 10분만에 아주 진하게 두줄이 나옴. 항원항체 반응이 격렬하게 일어났으므로, 항원이 몸에 겁나 많다고 할 수 있음. 24일 오전 동네 의원에 전화로 방문해서 확인하면된다고해 방문, 11시 10분경, 똑같은 테스트를 의사(!!)에게 받음. 20분 기다리라고 했으나, 10분만에 확진판정을 받음. 약을 받았음. 증상1. 목잠김. 이건, 완치가 되고서도 남아있음 (22.9.2 현재도 있음) 증상2. 몸살, 오한 흔한 감기 증상이라고 할 수 있음. 저녁시간 대에 유난히 심함. 증상3. 열. 24일 25일 26일 저녁 때마다 열 문제를 겪음. 증상4. 불면증, 의사말로는 아파서 그렇다는데, 약먹고는 많이 좋아졌으니 원인이 다른듯., 23일부터 26일 아침 7시까지 각성(커피를 과다마신 상태와 비슷함.) 상태로 있어서 잠을 잘 수 없음. 23일 커피를 오후에 마셔서 그런거라면, 뭔가 코로나 바이러스가, 카페인 민감증이나, 카페인 대사장애 같은 것을 일으킬 수도 있다는 가정을 해봄. 증상5. 슬슬 잠을 잘 수 있게 되니, 저녁에 있던 오한이나 몸살도 조금 가라 앉음. 대신 목에 가래가 끓기 시작함. 가래를 신체의 항원항체 반응이라고 생각하면, 이제 끝물이라고 생각할 수 있음. 증상6. 기침. 그냥 기침은 아니고, 가래가 끓었을 때, 가래를 배출하려는 신체반응으로 생각할 수 있음. 4일차부터 하루 3회 정도, 6일차에 들어서는 하루 1회정도로 변화함. 증상7. 밥맛이 사라지지는 않는데, 몸이 아파서 그리고 야외활동을 안하므로, 밥을 적게 먹었음. 탈수 증상도 없었으나, 몸무게가 2kg 정도 빠진걸로 확인.!! 첨부 예전에 신종플루를 유행후 3년되 즈음해서 걸렸는데, 그 때는 미각 장애를 겪었음. 미각 장애의 형태는, 기름 맛 과다측정이었음. 진라면 매운맛 컵라면을 먹는데, 너무 니글니글해서 먹을 수가 없었음. 그 때랑 비교해볼 때, 나 개인에게는 코로나로 미각장애는 없었다고 판단됨.

2022년 4월 18일 월요일

랑그릿사2 리버싱 - PC판 마법적용 방식(디버프 확률 관련 작동)

걸릴 확률이 존재하지 않는 버프, 디버프 마법은 제외하고 확률로 걸리는 

마법들을 설명합니다. 


존, 참, 슬립, 뮤트 등이 있습니다. 참의 경우에는 제 설명에 오류가 있을 가능성이 매우 큽니다. 

코드가 굉장히 복잡하기 때문입니다. 어떤진영인지 원래 어떤 진영인지 이런 정보들이 마구잡이로

들어있기 때문에 매우 복잡합니다. 


첫번째 포스트에서도 사용했던, 0x40ffd3 Apply_Spell_To_Target이라 명명한, 함수에서

switch(마법타입) case문을 통해서 관찰하였습니다. 


case Mute:

먼저 올바른 타겟 포스인지 체크합니다. 이 체크가, 진영을 보여주는건지 뭘 리턴하는건지 모르겠네요. 
일단 0을 리턴해야지만 마법이 걸립니다. 

그리고 Army Number가 0또는 7이어야 합니다. 강제로 1-6으로 용병 설정시 뮤트를 걸 수 없습니다. 

해당 유닛의 ArmyFlag의 MuteFlag 0x10이 0인지 체크합니다. 

마법 실행 플레그가 1이면 , 가장 먼저 마법이 성공할지를 계산하는 함수를 호출합니다. 
해당 함수는 0x0040f54d에 위치했습니다. 

이 함수는 먼저 마법방어력이 100인지 체크한 후 100이면, 마법 실패를 리턴합니다. 
다음 rng값을 구합니다. 

다음 100  -   ((공격자_LV - 방어자_LV) << 2) ) 를 수행합니다. 
음수 처리가 어떻게 될지는 잘 모르겠지만, 다시 쓰면

MDF - (공격자 - 방어자) X 4 의 값을 얻습니다. 편의상,  레벨차 보정 마방치라고 부르겠습니다. 

rng값에  %101을 취해 0-100의 난수를 얻습니다. 

난수 < 레벨차_보정 마방치 이면,     마법실패를 리턴하고, 아닌 경우 마법 성공 로직을 돌립니다. 

동일 레벨일 때, 마방치가 100이 아닌 99일 때,    0-98은 실패, 99와 100은 성공이므로,
확률은     1/100이 아닌   2/101입니다. 일단 마법 면역만 아니면 잘 걸립니다. 
잘 모르는 상태로 기대했던 것보다, 2배가량 높게 걸립니다. 

표로 보여드리면 다음과 같습니다. 

실패확률
공격자 방어자 레벨차
마방-8-4048
200.5150.3560.1980.0400.000
400.7130.5540.3960.2380.079
600.9110.7520.5940.4360.277
801.0000.9500.7920.6340.475
991.0001.0000.9800.8220.663
성공확률
공격자 방어자 레벨차
마방-8-4048
200.4850.6440.8020.9601.000
400.2870.4460.6040.7620.921
600.0890.2480.4060.5640.723
800.0000.0500.2080.3660.525
990.0000.0000.0200.1780.337
계산이 틀려보이신다면, 소수점 3번째 까지 나와서 그렇습니다. 99/101계산기로 해보시기를.

실패확률 부분을 보시면, 마방이 높을 수록 실패확률이 높고, 공격자의 레벨이 올라갈수록(오른쪽)
실패확률이 내려가는 것을 볼 수 있습니다. 

성공확률은 그 반대입니다. 

마방이 20이어도, 레벨만 높으면 50%는 저항을 합니다. 
마방이 99여도, 레벨이 낮으면 1/3은 마법이 걸립니다. 

case zone:

타겟이 맞는지를 체크한 후, 존플레그를 확인해서 안걸려 있으면 , 거는 로직으로 갑니다. 

실행 플레그가 없으면, 레벨마방보정치를 어딘가에 저장하고, 타겟수와 효과수에 1을 더합니다. 

실행플레그가 있으면, 마법이 성공하면, Zone_flag를 1로 해줍니다.  0x08


마법이 실패하면 다른 함수를 호출합니다. (왜????)
여기서 요상한 짓을 하는데, 마법 때마다, 어떤 메모리 공간에 올라와 있는 메모리 값을 
다른데다가 이동을 (시키고 위치x *48 +4, 위치y *48 -4) 값을 저장합니다. 


case sleep:

슬립도 시작은 타겟이 적합한지 먼저 체크를 하고, army타입이 불사가 아닌지를 체크합니다. 
불사는 슬립에 면역이도록 하드코딩 되어 있습니다. 종족값을 바꿀 때는 이걸 고려해야합니다.

실행플레그가 없을 때는, 존과 동일합니다. 

실행플레그가 있으면 성공일 때는 슬립 플레그를 1로 합니다. 슬립 플레그를 쓰는 비트필트는 , 
부대원별로 따로 존재합니다. 

슬립은 성공시에도, 다른 메모리 공간에 접근해서 위치를 저장합니다. 
 

case charm:

마지막으로 참입니다. 
참마법은 sleep과 동일합니다. 타겟체크, 불사체크 실행플레그 없을 때 동일입니다. 

참은 참이 걸려있던지 안걸려있던지를 확인을 안합니다. 

마법이 성공할지 체크를 먼저 합니다. 

실패시 실패 벡터공간에 데이터를 저장합니다. (다 동일 함수 사용)

성공시에 어떤 byte값이(b1) 0인지 체크합니다. 0이면, 
다른 바이트 값(b2)를 b1에 씁니다.      if(b1==0)   b1 = b2;

이어서 조건 없이 b2에   마법사용자의 b2값을 씁니다. 

추측을 해봅시다. b1은 원래진영번호, 0이면 변화없음이지 않을까. 

b2는 현재 진영번호라고 생각해보자. 

이어서 b1과 b2모두 1이 아닐 때,    b2 = 3을 쓴다. 

b1==b2면     b1 = 0 이다.  

그 다음 어떤 함수를 작동시키는데, 모든 타일에 있는 유닛들에 대해서, 뭔가를 건드린다. 
ArmyFlag 0x40이 참과 관련이 있는 것 같은데 아직 정보가 부족하며, 
적으로 바뀌면, 적들이 사용하는, force 정보공간으로 주소가 이전이 되는지, 

첫번째 hex값과 두번째 hex 값으로 force 넘버를 변조한다. 
근데 계산 과정에서 앞에서 바꾼 camp 번호값이 안 쓰인다. (??)

왜 재 계산을 하는건지 알 수 없다. 



참에 대해 조금더 들여다 보자(자가치유코드 다시보기)

루프를 돕니다. 먼저 원래의 캠프 값을 가져옵니다. 그 값이 0이면, 현재 캠프 값을 
다시 가져옵니다. 

얻어온 캠프값을  가지고 비트앤드 연산을 취한 뒤,  0이 아니어야 합니다. 

캠프값에 대한 정보가 아직 필요하지만, 현재 턴이오는 캠프가 아니면 자동회복 되지 않습니다.
어차피 한바퀴돌면, 자기턴이 올거라 무슨의미가 있을지는 알 수 없습니다. 

처음에 20개의 포스에 대해서, 루프를 돕니다. 
이 20개가 전체 전투가능한 지휘관 숫자면, 우리에게 참이걸린 적도 작동을 할테지만, 아니라면, 이상해 집니다. 

참이 걸려 우리편이 된 친구들은, 우리턴 시작에 자가회복이 된다고 일단 합시다. 

이 친구들은 인접위치의 부대원에게 체력 회복을 하고 가장 먼저, 참을 해제 합니다. 

확률 계산을 한 후, 원래캠프 번호가 0이 아니며, 참마법( ??) 플레그가 0(??)이면서,
 아미 플레그가 0x20이 없어야 합니다.  그리고 지휘관의 마법 방어력의 확률로 

마법을 해제합니다. 

마법해제 코드는 

   current_camp = initial_camp;   
  initial_camp = 0; 
입니다. 캠프 번호 두개가 참마법의 플레그로 보입니다. 

부대원 플레그 0x20, 포스 플레그 0x20은 미궁으로 빠집니다. 이름을 다시 지어야 겠습니다.
일단은 둘다 Absolute_Camp(enum값)로 이름을 바꾸고  사용처를 확인해야겠습니다. 






2022년 4월 14일 목요일

2022년 남은 기한 달력...

 

https://drive.google.com/file/d/1j9M9qYr3VK_VSo-1SexAQYtUHXWHKvxH/view?usp=sharing


디자인은 개판이지만... svg파일을 업로드 했으니... 색상은 본인이 직접 바꾸시면 되겠죠.


이게 저의 색상 감...입니다. 예술적인 감각이 많이 부족하죠.

2022년 4월 13일 수요일

랑그릿사2 리버싱 - PC판 마법적용 방식(버프,디버프마법 턴시작시 자가회복코드)

 


자가회복

오프셋 0041729e에 턴을 받을 때 자가회복을 하는 코드가 담겨 있습니다. 

모든 지휘관에 대해서 루프를 돕니다. 

참이 걸려있을 때는 권한이 이리저리로 넘어가서 복잡하게 작동합니다.  이게 진짜 내꺼지
체크하는 코드들이 여기저기 있는데, 이건 무시합시다. 

가장 먼저 자가회복이 가능한지 체크합니다.  먼저 지휘관의 classNum이 0xffff인지를 봅니다. 아니면 없는 부대입니다.   
이어서  체크는 armyFlag(spell)가 0x80인지, forceFlag(Spell)이 0x80인지 를 체크합니다. 아직 잘모르겠어서, 
첫번째 플레그는 MayBeDie라고 이름짓고, 다음 스테이트는 NoSelfHealState라고 이름을 붙였습니다. 나중에 이름이 바뀔 수도 있겠죠. 

이 플레그들을 하나만이라도 가지면, 회복이 되지 않는 Force가 됩니다. 


이걸 통과하면, 어떤 함수가 호출됩니다. 저는 heal_nearMyArmy()라고 이름을 지었습니다. 

해당 유닛의 옆의 자기 지휘관이 있는지를 체크한 후, 해당 위치에 회복을 거는 코드가 호출됩니다. 

해당위치의 회복을 거는 함수는, 해당위치의 forceNumber와 Army넘버(서수 0 지휘관 1-6 부대원 7 소환물)를 회복 시키는, healStack함수를 호출합니다. (이름은 다 제가 짓는 겁니다. )

healStack함수는 healPosition함수 외에도 한군데에서 호출이 되네요. 

오프셋 00417061입니다. 들어가서 보니, 마나를 +2하는 코드가 들어있습니다. 회복 명령을 찾았습니다. 이걸 따라 올라가면 명령체계가 분석이 되겠죠.

자 일단 하던거 마저 합시다. 

근처의 부대원을 회복하는 코드가 끝나면, 이제부터 잘 알려지지 않은 내용이 나옵니다. 

갑자기 착용아이템의 마방값을 구하는 코드가 들어옵니다. 
이어서, 레지스트 마법이 걸려있는지 체크합니다. 

다음 100보다 큰 마방을 다 100으로 고정합니다. 

디클레인은 여기 없습니다. 


마방을 다 구한 후, 디버프 마법의 자가회복이 시작됩니다. 

먼저 부대단위의 마법부터 시작합니다. 

처음은 참입니다. 플레그가 잔뜩있습니다. 이 플레그를 다 통과하고 나면, 마지막으로 랜덤함수를 호출한 후, MDF %만큼의 확률로 참을 해제합니다. 

다음은 존 마법입니다. 존 마법의 플레그는 존이 걸려있냐 하나 밖에 없습니다. 존이 걸려있다면,
마법방어력의 확률로 존 비트를 해제합니다. 

다음 부대단위 마법 플레그에 0xe1f8의   & 연산을 합니다. 
위 값의 1의 보수는 1e07입니다.    
   뒤의 7을 구성하는 1,2,4는 어택2, 프로텍트2, 레지스트 입니다. 모두 끕니다. 
   두번째 Hex는 그대로 갑니다. 
   세번째 Hex는 Attack(2), Protect(4), Quick(8)입니다.  끕니다. 
   네번째 Hex는 1은 디클레인 입니다. 

매 턴, 시작 때마다, 어택,프로텍트, 퀵, 디클레인, 레지스트를 끕니다. 강제사항입니다. 

부대원별 마법해제

이제 부대원별 자가해제 코드로 갑니다. 
부대원넘버 루프를 0--> 7까지 돕니다. (리더->>용병->> 소환물)

classNum이  0xffff가 아닌지 확인합니다. 

지휘관이 아닐 경우, 기존에 쓰던 마법 방어력 변수에 부대원 클래스 테이블 마방값을 
더합니다. 

아무래도 버그로 보입니다. 마법 데미지 공식에서, 부대원의 마방은 
레지스트+아뮬렛 +자체 마방인데, 영웅의 마방만큼 뺑튀기가 되었습니다. 
이러니, 게임에서 슬립을 걸면 발리스타가 걸렸다가 한턴만에 해제하는 것 아니겠습니까...
(뭐... 적들도 같은 루프 코드인지는 의문)

이 부분은 패치를 해야할 것으로 보입니다. 

그리고 100으로 제한하는 코드가 없습니다만, 앞의 값이 100으로 제한되고, 유닛 자체값이
최대 255(엔젤 FF)이므로 다 더했을 때, 355인데, 데이터 저장 공간이 Int(4byte)라서 
마방이 100일 때와 같은 결과를 얻습니다. 

위와 같은 방식으로 얻은 마방 값으로, 
슬립이 걸려있으면, RNG를 돌려 마방%의 값으로 마법을 해제합니다. 

이어서 뮤트가 걸려있으면, RNG를 돌려 마방%의 값으로 마법을 해제합니다. 

유닛이 마법이 쓸 수있는지 없는지는, 마법을 걸 때 판단을 하는 것 같습니다. 

루프를 마친 후, 로직을 마치고 게임 이펙트를 처리하는 부분으로 넘어갑니다. 



결론   


부대단위의 자가회복은 Resist + 마방아이템 + 지휘관 자체마방으로 이루어진다. 

부대원 단위의 마법은 지휘관은 위와 같은 마방으로 계산하고, 
지휘관이 아닌 경우는 Resist + 마방아이템 + 지휘관자체마방 + 용병(or소환수) 자체 마방을 
사용하며,  

마방%의 확률로 마법을 해제한다. 

공, 방, 마방, 속도의 영향을 주는 마법은 턴시작시 모두 해제한다. 

위에서 말하는 자가회복 마법 중,
     부대단위의 마법은 참과 존이다. 

위에서 말하는 자가회복 마법 중,
    부대원 단위의 마법은 슬립과 뮤트이다. 









2022년 4월 12일 화요일

랑그릿사2 리버싱 - PC판 마법적용 방식

읽다간 뭔가 선행지식이 필요하다 싶으시면,

https://langrisser2.blogspot.com/2019/08/7-2.html 

위 링크로 가셔서 앞부분을 학습하시기 바랍니다. 저도 저기서 많이 배웠습니다.  

뭔가 바이너리가 달라서 오프셋이 서로 일치하지 않는 문제가 있지만, 게임이 통째로 바뀔 정도로 

변혁이 있는건 아니기 때문에 참조하시기 충분합니다. 


1. 마법 적용 

오프셋 0041012c에 마법데미지 계산을 준비하는 함수가 있습니다. 

해당 함수에서는 마법공격력과 마법방어력에 대해, 마법과 아이템의 의한 변수를 미리 계산하여, 최종 마법 방어력을 계산하고, 마법별 공식과 상관이 없는 마법공격 변수를 구합니다. 

처음 만나는 if 함수에서 Resist마법이 걸려있는지 체크합니다. 랑그릿사에서는 마법 플레그가 걸려있는게 1인지 안걸려있는게 1인지 기준이 없습니다.  Resist는 또 1이 걸린거네요. 돌겠습니다. 
머리가 아픕니다. 

 그걸 잘 고려하셔서 해석하시면 되겠습니다. 

1. 레지스트가 걸려있으면, 마법방어력을 50으로 아니면 0으로 합니다. 

2-1. 지휘관일 경우, 마법데미지를 올리는 착용아이템의 효과의 합을 구합니다. 
    이어서, 마법방어력을 올리는 착용아이템의 효과의 합을 구합니다. 
  그리고 지휘관의  마법 방어력과 합합니다. 
(강제로 슬롯을 무시해 착용해도 작동함)

2-2. 지휘관이 아닐 시,  1에서 구한 마법방어력에 클래스별 고정 마법방어력 값을 더해줍니다. 
   방어구를 체크하여, 아뮬렛을 착용했으면, 마법 방어력을 15 더합니다. 

https://strategywiki.org/wiki/Langrisser_II/Spells#Attack_Spells
에서는 마법 방어력 아이템의 경우 x2를 적용 한다고 되어있지만, 그렇지 않습니다. 
저 분이 사용하신 게임과 제가 분석하는 게임이 다른 듯합니다. PC판 랑그릿사2는 
사실 굉장히 애매한 프로그램이라 그러려니 해주셔야 합니다. 

3. 디클레인이 걸려있는지 체크한 후 걸려있으면, 마법방어력을 15 뺍니다. 에러를 방지하기위해 15보다 작을시 미리 15로 값을 변경하는 로직이 있습니다. 

4. 마법방어력이 99보다 큰지 체크하여 크면, 100으로 고정합니다. 

5. 이유는 모르지만 마지막으로 글로벌 유닛타입변수에 해당 유닛의 유닛타입을 저장합니다. 


오프셋 0040ffd3에 마법을 타겟에 적용하는 함수가 있습니다. 

위의 일이 먼저 일어나고, 보너스마법데미지를 0으로 한후 ,
마법을 타겟에 적용하는 함수가 콜 됍니다. 

해당 파트는 들어가면 switch 문으로 현재 사용중인 마법을 적용하여 

해당 마법 코드를 작동합니다.  타겟이 이미 정해졌기 때문인지, 포스힐1 힐1은 같은 함수를 

호출합니다. 

현재사용중인 마법값이 소환마법일 경우는 이미 발키리로 고정되어 있습니다. 

2. 공격마법

고정되는 부분이 있어 먼저 설명합니다. 
 
데미지 계산식에  Lv >> 1 이라는 식으 무조건 들어갑니다. 그렇다보니 
https://strategywiki.org/wiki/Langrisser_II/Spells#Attack_Spells
에서는 이 부분을 MLv라고 부릅니다. 저도 그냥 그렇게 부르겠습니다.   대부분이 
저 곳에서의 값과 같습니다만, 다른 부분들이 꽤 있습니다. 아무래도 포팅하다가 코드를 건드려서 버그가 터진게 아닐까라는 생각이 듭니다. 

그리고 SP(스펠파워라고 부르자)라고, 클래스별 티어+1에 해당하는 값이 있다.  
클래스와 상관없이, 몇번째 전직인지가 중요한 값이다. 

마법데미지는 방무뎀과 마방적용 데미지로 나눠진다. 

방무뎀은 마법추가데미지와 (토네이도, 썬더용)  마법력강화 아이템으로 이루어진다. 

각 마법별로 달라지는 부분은 마방적용 데미지이다. 

완드와 같은 아이템이 제대로 작동하지 않는 느낌을 많이 받는데, 그 이유는 대부분 사용하는 마법이 파이어볼이고, 웬만하면 계산 결과가 damage* (100-마방)이   100보다 작아서 데미지가 0이라 하한값 1로 맞춰지기 때문입니다. 파이어볼만 죽어라 쓰기 때문이죠. 

매직에로우

매직에로우는 SP + MLV*2 이다.  

블라스트       

블라스트는 18 + MLV + SP 

썬더

썬더는 TileAttr이 타일이 수상(0x14)이거나 파괴지형이 수중(6)일 경우 보너스데미지 +1이 있다. 
썬더는  1+ MLv + SP 이다. 

파이어볼

파이어볼은 MLV + SP이다.    (가장 기본적이다. )

메테오

메테오는 6+ MLV + SP이다. 

블리자드, 토네이도, 어스퀘이크

불행하게도 모두 동일한 코드이다. 
(MLV + SP ) x 2 이다. 그냥 파이어볼 x2이다. 

토네이도 특이사항으로 비병에게 방무뎀이 +1 추가된다. 배우기 힘들어서 그렇지, 
유닛중심으로 쓰는 마법중 가장 강력하다. 그래서 버그로 보인다. 

특이 사항으로 어스퀘이크는 비병에게 적용되지 않는다. 

범위가 중요하긴 하겠지만, 마나소모가 2인친구가 가장 강력하고, 올라갈수록 약해지는건
뭔가 문제가 있다고 할 수 있다. 

외국위키와 비교.

아래는 해당 외국위키에서 참조하였다. [https://strategywiki.org/wiki/Langrisser_II/Spells#Attack_Spells]

메테오와 블라스트만  뭔가 명맥이 살아있고, 뭔가 전작(??)과의 연결점이 어딘가로 다사라지고 없다. 
마법 

나머지 마법 데미지 공식

오프셋으로 0040f429에 나머지 계산이 이루어진다. 

먼저 뭔가 값을 하나 찾는다. 해당 값이 0이면서 100-마방이 0이 아닐 때 나머지 코드가 이루어진다. 

마법데미지는 다음과 같다. 

  Bonus_Dmg(tornado,thunder) + SpellDmgItem +   마법별데미지*(100-MDF)%

그리고 이렇게 구한 값을    bound[1,targetHP]  <--- total_dmg
계산을 적용한다.  

결과 값을 볼 때, 지금 내가 가지고 있는 바이너리는 어릴 때 하던 쥬얼로 구매한 2CD물건과 다른것 같다. 완드의 효력을 별로 못 본 것 같은데, 엄청 강력하게 보인다. 


이어 총 얼마만큼의 데미지를 줬는지 누적치를 저장하고, 총 몇 스택에 효과를 주었는지 타겟누적치 값을 올린다. 

특정 플래그가 1이면 즉시 타겟에 HP에 영향을 주고, HP가 0이되면 유닛을 죽이는 회로를 작동 시킵니다. 이 회로에는 죽인 유닛의 살해경험치 값을 누적하고, 누적경험치가 255를 넘어가면 계속해서 255로 고정하는 로직이 포함되어 있습니다. 죽인 숫자 전역변수에 값을 1 더합니다. 

유닛을 파괴하고 소리가 나오고 이런건, 모든 계산이 이루어진 후, 따로 죽인숫자가 1보다 클 때 적용하는 부분이 있을 것으로 보입니다. 

3. 메테오 및 어스퀘이크 (지형붕괴 로직)

2번과 연결되는 부분으로 찾은게 아니라, 마법번호를 사용하는 코드를 ghidra로 찾았습니다. 

오프셋 - 00409cc6 에 위치한 함수에 있습니다. 
오프셋 -00409df2에  있는 어셈부터 보시면 됩니다. 


CMP dword ptr [ 00487e34] , 04 라고 적힌 부분이 있습니다. 
앞에 있는 주소값은, 현재 사용중인 마법의 넘버가 저장되는 장소입니다. (전역변수)

뒤에 있는 0x4는 메테오의 넘버입니다.  

현재 사용중인 마법이 메테오일시, 마법시전 좌표에 지형부수기 로직을 발동합니다. 


메테오 지형뿌수기의 오프셋은 00411cee입니다. 위의 CALL명령은 상대주소값을 사용해서, 
다릅니다만, 다른바이너리를 가지신 분은 저 hex를 검색한다거나 하는 방식으로 쉽게 찾으시지 않을 까생각합니다. 

지형 타입2가 0xff(파괴금지)가 아닐 시, 
좌표 X,Y의    지형1(스프라이트)를   원본 지형2로 
해당 좌표의 지형2를     원본 지형 1번으로 바꿉니다. 



이어서 메테오 함수 바로 아래에  cmp [   ] , 0x8이 있습니다. 
어스퀘이크일 때 작동 합니다. 
 
왜 이렇게 코딩이 되있는지 모르겠지만, 맵전체를 전부 돌면서, 마법범위 내의 지형을 전부 구합니다. 

이 범위내에 자기자신의 위치가 포함되있는지는 모르겠습니다. 

해당 지형 갯수의 1/4 갯수의 횟수만큼,  저 위치중의 한군데씩 파괴합니다. 

매회 같은 장소도 선택될 수 있기 때문에, 실제 파괴되는 것은, 훨씬 적고, 
다시 마법을 사용해도 마찬가지입니다.  횟수에 따라 기대값이 매우 떨어집니다. 

4. 중요한 발견, 

여기서 우리는 랜덤함수를 발견합니다. 이건 매우 중요합니다. 게임에서는 임의성이 중요합니다. 

게임리버싱의 핵심은 자료구조와, 랜덤함수 호출을 쫓는 것입니다. 랜덤함수는, 유저가 조작하지 않는부분에서는 나오지 않기 때문입니다. 

히어로즈3에서는 랜덤함수를 행운 계산식을 어디서 찾아서 바로, 나머지 사용되는 곳을 찾는 방식으로 리버싱을 하고 있습니다. 하지만, 랑그릿사는 이미 자료구조 파악이 많이 되서 이게 어떤 큰 변화를 줄지는 모르겠습니다. 

사용되는 숫자를 검색하니, 바로 랜덤함수라고 구글이 알려주는 군요. 처음 발견했을 때는, 숫자들이 길어서 메모리 값인줄 알고 놓쳤습니다. 

5. 힐 마법 

즉발 마법이 아닌 버프마법들은 코드가 지저분해서, 플레그 설정하는게 너무 어렵습니다. 나중으로 미룹니다. 텔레포트는 이제 발견해서 아직 못봤습니다. 

힐1과 힐2는 비슷합니다. 다른 부분은 하나입니다. 

힐1은 먼저 HP를 구합니다. 10-HP로 피해량을 구합니다. 

피해량이 0이면 함수를 리턴합니다. 

피해량이 크면 3으로 바운드 합니다. (힐2는 없음)

누적효과 값에 해당 값을 더합니다. 누적 타겟값을 1 증가시킵니다. 

실행 플레그가 있으면, 즉시 HP를 변경합니다. 

변경 후 공격마법에서 유닛을 죽였을 때, 사용한 전역변수에 1을 더합니다. 회복량과 관계 없이
회복시 마다 경험치가 1씩 늘어나는 것으로 보입니다.  


포스힐도 동일합니다. 타겟을 다른데서 정하기 때문입니다. 


감사합니다. 



6. 버프마법 디버프 마법

나중에...

2022년 3월 22일 화요일

HOMM3_리버싱 - 데쓰스테어 작동 로직.

 

일단 이 로직은, 유닛번호 체크를 해서, 강력한 고르곤에게만 작동하게 되어 있습니다. 

유닛이 살아있을 때, 유닛숫자만큼 루프를 돌면서,  1-100 dice < 11 계산 즉 10%의 확률로 

죽일 유닛숫자를 더합니다. 


다음 죽일 유닛에 숫자와 비교를 하는 코드가 있으나 잘못 보여주고 있는 것 같군요. 일단 최대값으로

상대 유닛숫자로 제한을 겁니다. 

dfsddfdfdfsdfsfsdfdf

이어서 중요한 부분이 보입니다. 고르곤의 숫자에다 +9를 더한후 10으로 나눕니다. 

그러면 소수점 버림 연산이 이루어지며, 1-10은 1로 11-20은 2로 상한선 값을 얻게 됩니다. 

이후 이 값으로 숫자를 바꿉니다. 

죽일 유닛의 숫자가 1보다 작다면 아무것도 이루어 지지 않습니다. 

-----------------------------------------------------------------------------------------------------------

이미 알려진 것과 다른 것은 없습니다. 알고 싶었던 것은 다만, 1/10을 넘어갈 때 어차피 필요 없으므로 즉시 종료하는지 아닌지에 대한 것이 었는데, 아주 무식하게 9999마리일 때, 9999번 계산을 수행한다는 사실이 추가될 뿐이죠. 

마무리하기전에 헛소리를 하나 하자면 고르곤을 먹고사는 러스트 드래곤은, 산성데미지가 25로 고정이 아니라, 러스트 드래곤의 최저 최대 데미지 사이에서 주사위로 값을 뽑아 러스트드래곤 수를 곱한후 나누기 2를 하는 것이더군요. 그런데 최저 최대 데미지가 50입니다. 블레스와 저주로 이런 상황을 만들면 아주 약소한 변화가 있겠다 할 수 있겠습니다. 


2021년 5월 10일 월요일

HOMM3 - Spell Fire Shield 데미지 계산식.

 

전투마법, 보조마법(버프)  - 
"불방패" (4)

16 스펠포인트를 사용하며, 1 Spell Power당 1라운드로 작동한다. 

Basic : 방어자가 받은 근접데미지의 20%의 데미지만큼, 공격자에게 불속성 마법데미지를 입힌다. 

Spell points 소모는 Basic 부터 12이다. 

Advanced : Basic과 같다. 다만 25%

Expert : Basic과 같다. 다만 30%

2021년 1월 20일 수요일

2020년 10월 19일 월요일

frei0r - 오픈소스 이미지 콤포지션(트랜지션) 상세설명.(1) - Mixer2 Part1 alpha...

    Frei0r

    Frei0r은 Natron이나 kdenlive같은 비디오 에디터에서 사용되는 composition,transition, merge 툴이다. 

    adobe의 트랙 매트 (track matte)효과를 kdenlive에서 어떻게 구현할지를 생각하다가 이것으로 구현할 수 있을 것 같아 찾다가, 너무 이름이 직관적이지 않아 쓸 때마다 헛갈릴 것 같아 정리를 해놓는다. 



    Mixer2 

    Mixer2는 8비트 unsigned int형의 자료를 사용하여 각 픽셀의 색상정보를 저장한다. Mixer3을 봐야 알겠지만, 더 큰 자료형을 사용하는 부분이 구현이 되어있지 않다면, frei0r은 사용하지 않는 것이 좋을 것이다.  

    코드 호출이 어떻게 되는지를 몰라서, 일단은 A를 윗 레이어, B를 아래 레이어로 생각하고 글을 쓴다.    kdenlive에 넣어서 테스트 해보니, A가 아래 B가 위로였다. natron에서는 다를 수 있으므로 1번 2번으로 전부 다시 고쳤다. 

     
    •  ᅟAddition (더하기)
    더하기 효과는 간단하다. 윗 이미지와 아래 이미지의 rgb값을 더 한다. 최대 값은 255로 한다. 

    알파의 값은 두 알파의 최소 값으로 한다. 

    고로 항등 image에 해당하는 윗 이미지는 (0,0,0,255)로 이루어진 이미지이다. 

    2번 레이어의 알파는 min연산이다보니, 중간 값을 이용하기 보다는, 이진의 마스크 효과를 사용할 수 있고, 윗 레이어를 통해 닷지 효과처럼 사용한다.  

    그리고 중요한 점 중 하나는, 윗레이어(마스크)와 아래레이어(배경)의 교환 법칙이 성립한다는 것이다. 많은 효과들이 교환 법칙이 성립하지만, 아닌 것들도 많다. gimp의 이미지 합성 툴 가운데에도 그런 것이 있다. 

    그룹레이어를 사용하지 못하는 경우에 교환 법칙이 성립하는 것을 유용하게 사용할 수 있고, (서로는 순서가 상관 없지만 그 각각도 위아래가 따로 있으므로 )노드 방식의 이미지 에디터에서 연결순서가 바뀌어도 같은 경과가 나오기에 유용하다. 이제 아래부터는 그냥 교환법칙이 성립한다로 끝내도록 한다. 


    • Addition_alpha (알파더하기)
    Addition_alpha는 대표적인 잘못이름지어진 콤포지션 효과이다. 
    이름만 들으면, 마스크의 알파 값이 더해질 것 같은 이름이지만 전혀 다른 효과를 가진다. 

    1번의 rgb에다가  pre-multiplied RGB(이하 pRGB) 값을 더하는 효과이며,
    결과값은 완전 불투명이다. 

    마치 이미지 에디터에서의 더하기라고 생각하면 된다. 레이어를 투명하게도 하지만, 브러쉬 툴의 알파를 이용해서 여러번 덧칠한다거나 하는 느낌을 주지 않을까??

    • Alphaatop( alpha atop)

    매우 복잡하다. 

    일단, 결과값의 알파는 2번의 알파와 같다. 

    결과의 알파가 0이라면, 리소스 낭비를 줄이기 위해 모든 결과값을 0으로 한다. 이후에도 알파값을 먼저 계산하면 다 그러해서 설명하지 않는다. 

    0이 아닐 때는,  다음과 같은 계산을 거친다. 

    w1 = alpha2

    w2 = 255 - alpha1

    rgb_dst = [(prgb1 * w1 ) + (prgb2*w2)]/ alpha_dst

    rgb_dst = rgb1*alpha1 + rgb2* [(1-alpha1)]

    직관적으로 이해하기 어렵다. 

    2번의 알파값이 그대로 작동하므로 알파마스크처럼 사용되며, 

    1번의 알파값에 따라, 1,2번의 색상의 rgb 사잇값을 사용한다. 

    • alphain 

    결과값의 알파는 1,2번 알파의 곱이다.  

    결과값의 RGB는 1번의 RGB값을 결과값의 RGB값으로 하도록 되어 있다. 

    rgb_dst = (rgb1*alpha1/255) * alpha2 / alpha_dst
    그렇다면 prgb_dst = rgb1*alpha1*alpha2가 될 것이다. 
    막상 약분이 된다고 하면, 
    rgb_dst = rgb1이다. 약간의 차이는 uint8 연산이다보니 여기저기서 계단 현상이 일어난다. 이것이 중요한 부분일지는 모르겠다. 

    어쨌든 대충 alpha_dst= alpha1*alpha2 
                      rgb_dst ≃ rgb1

    최신 깔끔한 구현에는 그냥 두번째 알파채널 또는, 레이어마스크 처럼 작동하지 않을까?

    단순한 알파마스크로 색상은 아무변화를 주지 못하며, 흰색일수록 불투명하다. 

    • alphainjection (오래된 api라 1,2번이 다를 수 있음)
    1번의 rgb값의 평균값을 결과값의 알파값으로, 2번의 rgb를 그대로 사용한다. 

    fill/key로 분리해서 전송하는것과 같다고 보면 된다. 

    물론 rgb의 평균값이 yuv채널의 y값과 다르기 때문에 생각한 것과는 다를 수 있다. 

    matte의 경우에는 루마 값을 알파값으로 사용한다. (kdenlive) 
    (matte는 frei0r이 아니다.  mlt framework sse!! code)

    alphainjection이 kdenlive에서는 없는 것처럼 보인다. 


    • alphaout
    alphaout은 alphain과 거의 같으나, 알파 대신 (255-alpha) 값을 사용한다. 반대로 작동한다. 시작효과를 끝에다가 붙인다면, 시작과 끝이 맞아서 아름답지 않을까?

    • alphaover
    무언가 수식만 봐도 미친 것 처럼 보인다. 편의상 0-1의 실수형 색상이라고 할 때, 결과값 알파는 다음과 같다. 

    alpha_dst = alpha1*alpha1 + alpha2*alpha2*(1-alpha1)
    alpha1과 alpha2의 제곱사이의 사잇값이다. 1번이 불투명할 때는, 약간의 변화를 2번의 알파가 주며, 알파2의 제곱이 알파1보다 작을 때는 오히려 더 투명하게 된다. 

    결과값 RGB는 다음과 같다.   

    rgb_dst= (rgb1 * alpha1 + pRGB2*(1-alpha1) )/ alpha_dst

    이건 써봐야 알 것 같기는 한데,  같은 수식을 그대로 적용한다. 

    1번에 있는 투명한 부분이 매우 밝게 강조 된다. 나누기 연산이 있으면 일단, 뭔가 특별한 상황에서만 써야지 결과값이 맛이 많이 간다. 



    • alphaxor
    alpha간 xor연산을 할 것 같지만 아니다. 또는 구현을 내가 몰라서일 수도 있다. (뭐 근데 xor연산을 다른 방법으로 하는건 좀 이상하다. 미치지 않고서는)

    결과값 alpha = alpha1*(1-alpha2)+ alpha2*(1-alpha1)
    모두 투명하거나 불투명하다면, 불투명하게, 
    하나만 투명할 때 투명하게 결과가 나온다. 

    비트 단위의 xor이 아닌 불투명도라는 정도에 대한 xor이다. 

    색상은 다음과 같다. 

    rgb_dst= (pRGB1 * (1-alpha2) + pRGB2* (1-alpha1) )/ alpha_dst

    pRGB에 대해 불투명한 레이어 쪽이 더 부각되도록 되어 있다. 

    교환 법칙이 성립한다.





    2020년 10월 5일 월요일

    남이 Natron으로 만든 Lower Third를 연습하다가 템플릿처럼 사용하는 방법을 알게 되었다.

     Natron은 node 기반 opensource vfx application이다. 

    vfx 및 드로잉 툴들은 어느정도 발전이 되었다면, node기반 또는 레이어 기반의 형태로 나아간다. 

    Node기반 툴들은 Davinci resolve,(NLE) Blackmagic Fusion(VFX)이라는 걸출한 유료프로그램이 있고, Blender라는 NLE, 3D modeling, Node vfx를 지원하는 툴도 있다. 

    Natron은 무료이며 일단 openfx기반이라 다양한 행위를 할 수 있다고 하는데, 그게 무슨 장점인지는 모르겠다.  

    Natron은 일단 Fusion이라는 툴을 써본 결과로 말하자면, 아무것도 배우지 않은 백지 상태에서는 차이를 알 수 없다.  왜냐 ... Layer기반을 쓰다가 이걸 처음 만지면, 어떻게 하는지 알수가 없기에... 그러하다.  뇌에서 Layer가 아닌 모든 것들이 다 공통으로 묶인 것으로 여겨진다. 

    Natron Youtube Lower third 강좌를 따라해보니, Natron은 결과물 출력으로 단일영상 또는 이미지시퀀스로  처리한다.  

    여기까지 따라하니, 내 이름을 특정 Text대신 쓰고난 이후에, 

    다양한 상황에서 쓰기 어렵다는 생각이 들어, 템플릿으로 쓸 방법을 찾는다. 

    일단 Natron Project파일은 xml기반이라, 노가다를 하고, nodejs를 사용하면, 텍스트 기반이니 당연히 가능하다.  

    일단 여러 검색을 해보니, Natron을 터미널에서 사용해, 출력물을 얻는 방법이 있음을 알게 되었다. 

    외부 툴을 사용하지 않고, Natron만 가지고 이것을 하고 싶다. xml은 구조화는 잘되어 있지만 인간이 접근하기 좋은 규격은 아니다. 

    Natron은 python script를 사용할 수 있고, 잘못검색을 하면, python을 프로젝트 파일처럼 사용하는 부분만 보게된다. 


    좀 더 신경을 쓰면, 프로젝트파일을 불러오고, onload시 python을 불러오는 옵션이 있다.

    -b는 터미널에서  바로 출력물을 얻겠다. 

    -l(L이다. ) 이 해당하는 python 스크립트이다. 

    natron -b Natron.project.ntp -l python1.py 

    이 두 명령으로 python1실행으로 내부가 변한 상태의 출력물을 얻을 수 있다. 

    저 python1.py의 구조가 이제 중요하다. 


    내부 노드에 어떻게 접근을 할 수 있을까?

    Natron은 일단 프로젝트 파일을 불러온 후 프로젝트 xml을 잘 정리해서 app1이라는 클래스에 모든 정보를 넣는다. 그리고 노드이름으로 간단히 접근할 수 있다. 

     1  
     2 node = app1.Text1
     3  
     4 node.text.set("hello World")

    내 경우는 위 처럼 2줄짜리 프로그램으로 글자를 바꿀 수 있게 된다. 

    뭐 더 고친다면 소속까지 한 줄 더 작성하는 정도이겠다. 

    자이제 natron 명령으로 여러명의 개인 소개용 Lower Third를 만들도록하자. 

    bash까지 사용하면 못할게 없고, sed 명령어를 사용해 쉽게 작업할 수 있다. 

    (sed를 사용하면, 애초에 매우 쉽다. )


    자료리스트

    konkuk으로 시작하는 친구들은, writer까지 작업이 되어있어서 편리하다. 원본이랑 사실 별차이 없다. 

    300프레임에 25MB정도씩 나와서 생각보다 무겁지만 재미있는 작업이 될 것이다. 

    csv파일로 로고파일주소, Text1 내용  Text_2 내용 등을 만들어 놓으면, 여러사람에 대해 설명하는 작업을 해서 재미있게 할 수 있을 것이다. 


    열심히 썼지만, 문제가 있는데, Natron은 저 움직이는 이미지 작업 자체가 더럽다. 뭐... 개인적으로 3D Text의 두깨 기능이 지원이 안되서, 배우는건 Natron으로 하고, 실지로는 Blender를 쓰지 않을까... 


    돈있으면, after effect용 템플릿을 구하면 된다. 


    이 글에서 가장 중요한건, app1이라는 클래스 이름이다. 

    우분투 리눅스에서 모니터 오버클락하기.

     

    리눅스에서 디스플레이 해상도 등과 관련된 패키지는 xrandr이다. 


    xrandr을 통해 다양한 display mode를 체험할 수 있다. 


    지금 현재 사용하고 있는, 모니터는 DELL 2312HM으로 홈페이지상 스펙으로는  1920x1080  60이 한계인 것으로 나타난다. 


    처음 xrandr을 누르면, 이 이하의 설정가능한 다양한 해상도 등이 나온다. 

    1080x1024 75.02 60 

    640x480 75 59.94 

    등이 나오는데, 이 값들은 일종의 디스플레이 업계의 약속된 추천해상도라고 할 수 있다. 


    윈도우 시스템의 경우는 드라이버에 따라서, 굉장히 다양한 해상도 설정이 가능한 경우가 있는데, 이 해상도들은, 일종의 업계 호환해상도라고 할 수 있다. 


    이 호환 해상도에 해당하는 것이 바로 gtf, cvt라는 것이다. (위키에 검색해보시오)


    여기에는 그래픽카드에서 모니터로 신호를 보낼 때, 어떤 주파수로 신호를 보내고, 어디서부터 어디까지인지 신호를 보낼지에 대한 일종의 약속이다. 이 신호는 결국 픽셀정보를 직렬로 보내다보니 직사각형의 화면정보를 열별로 나누어 보내게 되고,  어디부터 시작인지 어디가 끝인지, 열의 시작과 끝이 어디인지 및 몇가지 정보전달을 위한  위한 메타데이터를 필요로 하게되고 이러한 값들이 직사각형 정보덩어리의  테두리 여백으로 들어가게 된다. 

    기본 규약은 어차피 자동으로 처리가 되므로 필요한 것은 저 호환 해상도에 해당하는 gtf와 cvt이다. 

    리눅스의 경우 gtf를 누르면 다음처럼 나오고,

    원하는 해상도를 입력하면 다음처럼 나온다. 

    cvt의 경우도 마찬가지이다. 




    이렇게 얻은 정보를 가지고 xrandr를 사용하여 추가하여 사용할 수 있다. (싱글모니터는 요렇게하지만 듀얼부터는 몇자를 더적어야)

    Modeline 뒷 정보를 다음처럼,
    xrandr --newmode "1920x1080_60.00"  173.00  1920 2048 2248 2576  1080 1083 1088 1120 -hsync +vsync
    xrandr --addmode "1920x1080_60.00"

    xrandr --mode "1920x1080_60.00"



    이제부터 모니터 오버클럭이야기를 해보자. 


    원래부터 지원되는 해상도임에도 불구하고 저렇게 입력하면, dvi single link나(대부분 와이드 해상도 면... 맞아...) 오래된 hdmi 버전을 쓰는 모니터는 먹통이 된다.   저 첫번째 숫자부분이 165를 넘어가면 먹통이 된다. (내 테스트는 164도 먹통이었음 163.xx까지는 잘 되었음. 이 현상은 케이블 먹통이라 하자.) 

     당연히 약속이 잘되어 있는 친구들이, 메타데이터가 덜 필요하다. 약속만 되어 있으면, 봉화 몇개로도, 전쟁유무가 파악되는 법 ...  

    예비약속이다보니, 더 많은 정보가 필요하다.  


    이 예비약속들만으로는 되지 않는다. 윈도우 처럼 넘실거리는 수많은 모니터 해상도 지원은 가능하지만, 오버클럭은 불가능하다. 

    아날로그 시대에 비해 디지털 시대에 HD가 붙기 시작하는 친구들은 해상도가 더 큰 편이다보니, 메타데이터를 잘 접어서 구석에  넣는 방법이 생겼다. 

    (이 문장은 내 개인 추측이다. 틀렸을 수 있다. )

    그 방법을 cvt-rb 방식이라 한다. 

    https://en.wikipedia.org/wiki/Coordinated_Video_Timings#Reduced_blanking 

    우분투에서는 cvt-rb 방식을 apt로 받는 cvt에서 지원을 한다. 


    보면 알겠지만, 갑자기 165MHz까지 가기에는 많이 남게된다. 

    그런데 안타깝게도, 이 규약은 원래 나올 때, 60Hz의 배수만을 지원하기 위해 나왔다. (아마 표준 나오고 빠른 모니터가 너무 빨리 나왔을때 나온걸로 보인다)

    그러다보니 이툴은 60-120hz사이의 다른값들을 쓰기에 부적절하다. 뭐 구글에 linux monitor overclock이라 검색하면 수정된 cvt와 더 다르게 구겨넣는  방식인 cvt-rb2까지 지원하는 녀석이 깃헛에 있음을 알 수 있다. 

    wget http://www.uruk.org/~erich/projects/cvt/cvt.c

    $ curl https://raw.githubusercontent.com/kevinlekiller/cvt_modeline_calculator_12/master/cvt12.c --output cvt12.c

    Compilation:

    $ gcc cvt12.c -O2 -o cvt12 -lm -Wall

    앞 친구는 60hz 배수를 써야하는 규약을 무시하고 중간 친구들을 만들어주고, 뒷친구는 cvt-rb2까지 지원을 하는 친구인데 뒤에걸 일단 쓰는 걸로 하자. 뒤에 것은 c 옵션으로 강제조항이 있다. 

    그 방법을 통해 60까지 지원하는 h2312hm을 


    Modeline "1920x1080_73.86_rb2"  164.99 까지 올렸다. 

    일단 강제조항을 써서 얻은 cvt-rb는 dell이 나름 메인스트림 회사라 지원을 제대로 안한다. 이상한 회사라면 지원했을 수도 있어서 .. 75성공했을텐데... 


    일단 dvi-d sigle-link에서는 이 이상 올릴 수가 없다. 

    일단 저위에 그림처럼, 24라는 표준 깜빡임의 배수로 설정할 예정이다만, 저정도로 가득채워서 올릴 수 있다. 


    나중에 display port를 지원하는 그래픽카드가 있으면 좀 더 노력을 해보겠다. 


      이러한 방식으로 linux에서는 디스플레이 오버클럭을 한다. 

    모니터가 지원을 안하고 힘들어 할 수 있지만, 보통은 여유를 가지고 지원을 해주므로,  refresh 속도를  더 올려보자. 

    내 모니터는 75정도에서 한계점을 가진게 맞는지... 1280 720에서 여유가 많이 있음에도 120 90은 실패했다. 

    여러번의 시도를 거치면 적당한 해상도에서 최대 refresh값을 얻을 수 있지 않을까... 리눅스는 노가다다. 



    2020년 9월 24일 목요일

    Image Compositing 정리. 1 (Screen, Multiply) 스크린, 곱하기


    Screen은  검은색 배경으로 된 VFX를 합성할 때 사용되고는 한다. 

    공식상, 검은색의 레이어는 원본의 색을 그대로 노출하고, 흰색의 레이어는 완전히 (RGB  각 값도 마찬가지)  아래의 값을 지워버린다. 

    RGB, 원색 레이어를 통해 해당 색의 보색에 대한 필터로 작용할 수 있다. 

    중간단계에서 보이는 부분이 재미있는데, 레이어의 색상으로 부터 최대값까지 색상을 압축하면서, 뒷면의 색상차는 그대로 보여줄 수 있다. 

    24bit(8bit rgb) 이기 때문에 계단 현상은 생길 수 있으나, 뒷배경을 보이면서 오버레이어의 밝기 까지 보여 줄 수 있기 때문에 아주 유용하게 사용된다. 

    인터넷에 있는 번개, 폭발 연기 등의 프리소스를 사용하여 오버레이어의 콤포지터를 Screen으로 사용하도록 하자. 


    곱하기 효과는 Screen과는 반대로 작용한다. 흰색일 때는, 베이스 컬러를 그대로 보여주고, 검정색일 때는 검은색이 되어버린다. 

    레이어의 색상을 최대값으로  검정색으로부터 베이스의 색상을 압축하여 표현된다.

    R,G,B 의 원색을 사용하여 특정 채널만 뽑는데만도 사용할 수 있다. 

    배경이 흰색이 소스를 합성할 때 사용하면 좋다.  그러나 배경이 흰색인 소스의 합성은 주로 Y-채널을 조작해  Alpha로 사용하는 Luma Key를 많이 사용한다.    이건 뭔가 사람의 눈과 관련이 있을 것으로 보인다. 빛이 비춰 밝아진 물체를 구분하기는 쉽지만, 특정 부분만 어두워 지는것을 구분하는 일이 더 적어 질 것 같기는 하다. 

    2020년 8월 25일 화요일

    NFC Tag로 Wifi 공유하기. (Android, NFC Tools)



    NFC Tools 어플리케이션을 킨다. 


    Write Tab에가서 Add a record로 들어간다. 아래로 스크롤하여 

    Wi-Fi network를 누른다. 


    돋보기 버튼을 누른다. 근처에 있는 모든 네크워크가 뜨므로 오른 쪽 상단에 

    Wi-Fi가 양쪽으로 나가는 아이콘을 클릭한다. (제목 우측:Available Wi-Fi networks)

    잠시후 가까이에 있는 Wi-Fi 즉 내가 작업할 놈이 최상단에 뜰 것이다. 


    그것을 누르고 Authentication 은 가정용에서는 WPA/WPA2-Personal을

    고르면 되고, password는 그대로 가져와서 쓰면 된다. 


    그리고 OK를 누르고 나간면 Write / 약 100bytes  와 같은 버튼이 있다.


    그것을 누르고 빈 NFC Tag에 가져다 댄다.  

    그러면 Wi-Fi에 관한 모든 정보가 기입된다. 



    모든 작업이 완료되었다. 안드로이드 기기간에는 약속된 NFC Tag기능이 있는데 그 중 하나가 Wi-Fi Network을 추가 하는 것이다.  


    이제 다른 사람의 핸드폰 또는 본인의 핸드폰에서 해당 비밀번호를 초기화 한후 비접촉 방식으로 접속해보자. 


    나 같은 경우는, NTAG213이라는 제품을 사용하다보니 최대 144바이트를 쓸 수 있어서 비밀번호 원문이 그대로 Tag에 노출된다. 

    Wi-Fi 비밀번호를 만들 때, 중복되지 않는 임의의 비밀번호를 생성한다면 노출이 된다해도 나중에 수정하면 된다. 다만 다른데서 쓰는 비밀번호를 그대로 쓰고 싶다면 다른 방법을 사용해보자. 


    다른 툴을 사용하면, 비밀번호를 Hash 값으로 바꿀 수 있다. 나 같은 경우는 wpa_passphrase를 사용하는데 이것을 통하면, 65자리의 Hash가 얻어진다. 

    요렇게 했을 때, 원문 비밀번호는 노출이 되지 않으나(무작위 대입방법에는 취약하니 영어만 쓴다거나 하면 안된다. 그냥 랜덤값 쓰고 본인도 NFC 터치로만 연결하자. )


      애매하게 150byte정도를 쓰는데 이건 내 ssid가 긴 문제인 것 같다만, (어차피 터치로 할거니 짧듯 길든 무슨 상관...) 


    NTAG 213은 144바이트 밖에 안되서 제약이 많으므로 NTAG215(504bytes) 나  NTAG216(888bytes)를 애초에 구매를 해서 사용하는 방법을 쓰면 좋다. 


    215도 ebay에서 213보다 비싸지만 약간의 차이이니 이것을 추천한다. 나도 213이 너무 작아서 다음에 구입 예정이다. 


    213은 머리 맡에 가져다 대면, 손전등이 켜지게 하거나, 블루투스 오디오를 바로 연결하게 하는 등 보안과 상관 없는 간편작업에 쓰면 좋을 것이다.

    비밀번호는 원문공개를 항상 조심하자. 몇년전에 한국물리학회홈페이지에서 비밀번호 찾기를 했는데, 원문이 그대로 와서 식겁했다. 그 때 이미 불법이었는데... 그러고서도 몇년동안 그대로였는데, 여기는... 비밀번호가 털렸는지 확인조차 제대로 안되었을 것 같아서.. 걱정을 많이 했는데 여러분도 그럴 필요는 없으니, 대충 쓰는 비번은 중요한 비번과 겹치지 않게 잘 하자. 

    가장 많이 본 글